From 62a3b1ed3553337a8ffc78134189b77534541b6b Mon Sep 17 00:00:00 2001 From: Jan Andrle Date: Sat, 9 Sep 2023 21:15:43 +0200 Subject: [PATCH] :bug: :construction: connected/disconnected + onAbort --- dist/dde-with-signals.js | 288 ++++++++++++++++-------------- dist/dde.js | 268 ++++++++++++++------------- dist/esm-with-signals.js | 288 ++++++++++++++++-------------- dist/esm.js | 268 ++++++++++++++------------- index.d.ts | 17 +- package.json | 3 +- src/dom.js | 8 +- src/events.js | 28 +-- src/helpers.js | 10 ++ src/signals-lib.js | 2 + src/signals.d.ts | 2 +- test/components/todosComponent.js | 27 ++- test/components/webComponent.js | 49 +++++ test/exports.js | 13 +- test/index.js | 3 + 15 files changed, 718 insertions(+), 556 deletions(-) create mode 100644 test/components/webComponent.js diff --git a/dist/dde-with-signals.js b/dist/dde-with-signals.js index ca62291..e39bb57 100644 --- a/dist/dde-with-signals.js +++ b/dist/dde-with-signals.js @@ -1,228 +1,245 @@ //deka-dom-el library is available via global namespace `dde` (()=> { // src/helpers.js - function m(e) { + function g(e) { let t = typeof e; return t !== "object" ? t : e === null ? "null" : Object.prototype.toString.call(e); } + function j(e, t) { + if (!e || !(e instanceof AbortSignal)) + return !0; + if (!e.aborted) + return e.addEventListener("abort", t), function() { + e.removeEventListener("abort", t); + }; + } // src/signals-common.js var b = { isTextContent(e) { - return m(e) !== "[object Object]"; + return g(e) !== "[object Object]"; }, processReactiveAttribute(e, t, n, r) { return n; } }; - function j(e, t = !0) { + function N(e, t = !0) { return t ? Object.assign(b, e) : (Object.setPrototypeOf(e, b), e); } - function N(e) { + function A(e) { return b.isPrototypeOf(e) && e !== b ? e : b; } // src/dom.js - var v = "html"; - function ee(e) { - return v = e === "svg" ? "http://www.w3.org/2000/svg" : e, { + var y = "html"; + function te(e) { + return y = e === "svg" ? "http://www.w3.org/2000/svg" : e, { append(t) { - return v = "html", t; + return y = "html", t; } }; } - function te(e, t, ...n) { - let r = N(this), o; + function ne(e, t, ...n) { + let r = A(this), o; switch (r.isTextContent(t) && (t = { textContent: t }), !0) { - case typeof e == "function": - o = e(t || void 0); + case typeof e == "function": { + o = e(t || void 0, (s) => s ? (n.unshift(s), void 0) : o); break; + } case e === "#text": - o = y(document.createTextNode(""), t); + o = w(document.createTextNode(""), t); break; case e === "<>": - o = y(document.createDocumentFragment(), t); + o = w(document.createDocumentFragment(), t); break; - case v !== "html": - o = y(document.createElementNS(v, e), t); + case y !== "html": + o = w(document.createElementNS(y, e), t); break; case !o: - o = y(document.createElement(e), t); + o = w(document.createElement(e), t); } return n.forEach((a) => a(o)), o; } var x = new Map(JSON.parse('[["#text,textContent",true],["HTMLElement,textContent",true],["HTMLElement,className",true]]')); - function y(e, ...t) { - let n = N(this); + function w(e, ...t) { + let n = A(this); if (!t.length) return e; - let r = e instanceof SVGElement, o = (r ? q : D).bind(null, e, "Attribute"); - return Object.entries(Object.assign({}, ...t)).forEach(function a([f, s]) { - s = n.processReactiveAttribute(e, f, s, a); - let [h] = f; + let r = e instanceof SVGElement, o = (r ? J : T).bind(null, e, "Attribute"); + return Object.entries(Object.assign({}, ...t)).forEach(function a([s, i]) { + i = n.processReactiveAttribute(e, s, i, a); + let [h] = s; if (h === "=") - return o(f.slice(1), s); + return o(s.slice(1), i); if (h === ".") - return _(e, f.slice(1), s); - if (typeof s == "object") - switch (f) { + return _(e, s.slice(1), i); + if (typeof i == "object") + switch (s) { case "style": - return w(s, D.bind(null, e.style, "Property")); + return O(i, T.bind(null, e.style, "Property")); case "dataset": - return w(s, _.bind(null, e.dataset)); + return O(i, _.bind(null, e.dataset)); case "ariaset": - return w(s, (E, O) => o("aria-" + E, O)); + return O(i, (E, v) => o("aria-" + E, v)); case "classList": - return $(e, s); + return k(e, i); default: - return Reflect.set(e, f, s); + return Reflect.set(e, s, i); } - if (/(aria|data)([A-Z])/.test(f)) - return f = f.replace(/([a-z])([A-Z])/g, "$1-$2").toLowerCase(), o(f, s); - switch (f) { + if (/(aria|data)([A-Z])/.test(s)) + return s = s.replace(/([a-z])([A-Z])/g, "$1-$2").toLowerCase(), o(s, i); + switch (s) { case "href": - return o(f, s); + return o(s, i); case "xlink:href": - return o(f, s, "http://www.w3.org/1999/xlink"); + return o(s, i, "http://www.w3.org/1999/xlink"); case "textContent": if (!r) break; - return e.appendChild(document.createTextNode(s)); + return e.appendChild(document.createTextNode(i)); } - return k(e, f) ? _(e, f, s) : o(f, s); + return q(e, s) ? _(e, s, i) : o(s, i); }), e; } - function $(e, t) { - return typeof t != "object" || w( + function k(e, t) { + return typeof t != "object" || O( t, (n, r) => e.classList.toggle(n, r === -1 ? void 0 : !!r) ), e; } - function ne(e) { + function re(e) { return Array.from(e.children).forEach((t) => t.remove()), e; } - function k(e, t) { + function q(e, t) { let n = "HTMLElement," + t; if (e instanceof HTMLElement && x.has(n)) return x.get(n); let r = e.nodeName + "," + t; if (x.has(r)) return x.get(r); - let [o, a, f] = T(e, t), s = !A(o.set); - return (!s || a) && x.set(f === HTMLElement.prototype ? n : r, s), s; + let [o, a, s] = M(e, t), i = !P(o.set); + return (!i || a) && x.set(s === HTMLElement.prototype ? n : r, i), i; } - function T(e, t, n = 0) { + function M(e, t, n = 0) { if (e = Object.getPrototypeOf(e), !e) return [{}, n, e]; let r = Object.getOwnPropertyDescriptor(e, t); - return r ? [r, n, e] : T(e, t, n + 1); + return r ? [r, n, e] : M(e, t, n + 1); } - function w(e, t) { + function O(e, t) { return Object.entries(e).forEach(([n, r]) => t(n, r)); } - function A(e) { + function P(e) { return typeof e > "u"; } - function D(e, t, n, r) { - return e[(A(r) ? "remove" : "set") + t](n, r); + function T(e, t, n, r) { + return e[(P(r) ? "remove" : "set") + t](n, r); } - function q(e, t, n, r, o = null) { - return e[(A(r) ? "remove" : "set") + t + "NS"](o, n, r); + function J(e, t, n, r, o = null) { + return e[(P(r) ? "remove" : "set") + t + "NS"](o, n, r); } function _(e, t, n) { return Reflect.set(e, t, n); } // src/events.js - function M(e, t, n) { - return (r) => (r.addEventListener(e, t, n), r); + function ce(e, t, ...n) { + let r = n.length ? new CustomEvent(t, { detail: n[0] }) : new Event(t); + return e.dispatchEvent(r); } - var S = J(); - M.connected = function(e, t) { + function H(e, t, n) { + return function(o) { + return o.addEventListener(e, t, n), o; + }; + } + var S = W(); + H.connected = function(e, t) { return function(r) { - S.onConnected(r, e), t && t.signal && t.signal.addEventListener("abort", () => S.offConnected(r, e)); + return j(t && t.signal, () => S.offConnected(r, e)) && S.onConnected(r, e), r; }; }; - M.disconnected = function(e, t) { + H.disconnected = function(e, t) { return function(r) { - S.onDisconnected(r, e), t && t.signal && t.signal.addEventListener("abort", () => S.offDisconnected(r, e)); + return j(t && t.signal, () => S.offDisconnected(r, e)) && S.onDisconnected(r, e), r; }; }; - function J() { + function W() { let e = /* @__PURE__ */ new Map(), t = !1, n = new MutationObserver(function(c) { - for (let i of c) - if (i.type === "childList") { - if (E(i.addedNodes, !0)) { - f(); + for (let f of c) + if (f.type === "childList") { + if (E(f.addedNodes, !0)) { + s(); continue; } - O(i.removedNodes, !0) && f(); + v(f.removedNodes, !0) && s(); } }); return { - onConnected(c, i) { - a(), o(c).connected.push(i); + onConnected(c, f) { + a(), o(c).connected.push(f); }, - offConnected(c, i) { + offConnected(c, f) { if (!e.has(c)) return; let u = e.get(c), l = u.connected; - l.splice(l.indexOf(i), 1), r(c, u); + l.splice(l.indexOf(f), 1), r(c, u); }, - onDisconnected(c, i) { - a(), o(c).disconnected.push(i); + onDisconnected(c, f) { + a(), o(c).disconnected.push(f); }, - offDisconnected(c, i) { + offDisconnected(c, f) { if (!e.has(c)) return; let u = e.get(c), l = u.disconnected; - l.splice(l.indexOf(i), 1), r(c, u); + l.splice(l.indexOf(f), 1), r(c, u); } }; - function r(c, i) { - i.connected.length || i.disconnect.length || (e.delete(c), f()); + function r(c, f) { + f.connected.length || f.disconnected.length || (e.delete(c), s()); } function o(c) { if (e.has(c)) return e.get(c); - let i = { connected: [], disconnected: [] }; - return e.set(c, i), i; + let f = { connected: [], disconnected: [] }; + return e.set(c, f), f; } function a() { t || (t = !0, n.observe(document.body, { childList: !0, subtree: !0 })); } - function f() { + function s() { !t || e.size || (t = !1, n.disconnect()); } - function s() { + function i() { return new Promise(function(c) { (requestIdleCallback || requestAnimationFrame)(c); }); } async function h(c) { - e.size > 30 && await s(); - let i = []; + e.size > 30 && await i(); + let f = []; if (!(c instanceof Node)) - return i; + return f; for (let u of e.keys()) - u === c || !(u instanceof Node) || c.contains(u) && i.push(u); - return i; + u === c || !(u instanceof Node) || c.contains(u) && f.push(u); + return f; } - function E(c, i) { + function E(c, f) { for (let u of c) { - if (i && h(u).then(E), !e.has(u)) - return !1; + if (f && h(u).then(E), !e.has(u)) + continue; let l = e.get(u); return l.connected.forEach((L) => L(u)), l.connected.length = 0, l.disconnected.length || e.delete(u), !0; } + return !1; } - function O(c, i) { + function v(c, f) { for (let u of c) { - if (i && h(u).then(O), !e.has(u)) - return !1; + if (f && h(u).then(v), !e.has(u)) + continue; let l = e.get(u); return l.disconnected.forEach((L) => L(u)), l.connected.length = 0, l.disconnected.length = 0, e.delete(u), !0; } + return !1; } } @@ -244,15 +261,15 @@ } } var p = /* @__PURE__ */ new WeakMap(); - function g(e, t) { + function m(e, t) { if (typeof e != "function") - return H(e, t); + return z(e, t); if (C(e)) return e; - let n = H(""), r = () => n(e()); + let n = z(""), r = () => n(e()); return p.set(r, /* @__PURE__ */ new Set([n])), Z(r), n; } - g.action = function(e, t, ...n) { + m.action = function(e, t, ...n) { let r = e[d], { actions: o } = r; if (!o || !Reflect.has(o, t)) throw new Error(`'${e}' has no action with name '${t}'!`); @@ -260,22 +277,22 @@ return Reflect.deleteProperty(r, "skip"); r.listeners.forEach((a) => a(r.value)); }; - g.on = function e(t, n, r = {}) { + m.on = function e(t, n, r = {}) { let { signal: o } = r; if (!(o && o.aborted)) { if (Array.isArray(t)) return t.forEach((a) => e(a, n, r)); - P(t, n), o && o.addEventListener("abort", () => F(t, n)); + D(t, n), o && o.addEventListener("abort", () => $(t, n)); } }; - g.symbols = { + m.symbols = { signal: d, onclear: Symbol.for("Signal.onclear") }; - g.clear = function(...e) { + m.clear = function(...e) { for (let n of e) { Reflect.deleteProperty(n, "toJSON"); - let r = n[d], { onclear: o } = g.symbols; + let r = n[d], { onclear: o } = m.symbols; r.actions && r.actions[o] && r.actions[o].call(r), t(n, r), Reflect.deleteProperty(n, d); } function t(n, r) { @@ -283,48 +300,48 @@ if (r.listeners.delete(o), !p.has(o)) return; let a = p.get(o); - a.delete(n), !(a.size > 1) && (g.clear(...a), p.delete(o)); + a.delete(n), !(a.size > 1) && (m.clear(...a), p.delete(o)); }); } }; - g.el = function(e, t) { + m.el = function(e, t) { let n = document.createComment("<#reactive>"), r = document.createComment(""), o = document.createDocumentFragment(); o.append(n, r); - let a = (f) => { + let a = (s) => { if (!n.parentNode || !r.parentNode) - return F(e, a); - let s = t(f); - Array.isArray(s) || (s = [s]); + return $(e, a); + let i = t(s); + Array.isArray(i) || (i = [i]); let h = n; for (; (h = n.nextSibling) !== r; ) h.remove(); - n.after(...s); + n.after(...i); }; - return P(e, a), a(e()), o; + return D(e, a), a(e()), o; }; - var z = { + var F = { isTextContent(e) { - return m(e) === "string" || C(e) && m(V(e)) === "string"; + return g(e) === "string" || C(e) && g(K(e)) === "string"; }, processReactiveAttribute(e, t, n, r) { - return C(n) ? (P(n, (o) => r([t, o])), n()) : n; + return C(n) ? (D(n, (o) => r([t, o])), n()) : n; } }; - function H(e, t) { - let n = (...r) => r.length ? U(n, r[0]) : G(n); - return I(n, e, t); + function z(e, t) { + let n = (...r) => r.length ? V(n, r[0]) : G(n); + return U(n, e, t); } - var W = Object.assign(/* @__PURE__ */ Object.create(null), { + var I = Object.assign(/* @__PURE__ */ Object.create(null), { stopPropagation() { this.skip = !0; } }); - function I(e, t, n) { - return m(n) !== "[object Object]" && (n = {}), e[d] = { + function U(e, t, n) { + return g(n) !== "[object Object]" && (n = {}), e[d] = { value: t, actions: n, listeners: /* @__PURE__ */ new Set() - }, e.toJSON = () => e(), Object.setPrototypeOf(e[d], W), e; + }, e.toJSON = () => e(), Object.setPrototypeOf(e[d], I), e; } var R = []; function Z(e) { @@ -342,37 +359,40 @@ let { value: t, listeners: n } = e[d], r = B(); return r && n.add(r), p.has(r) && p.get(r).add(e), t; } - function U(e, t) { + function V(e, t) { if (!e[d]) return; let n = e[d]; if (n.value !== t) return n.value = t, n.listeners.forEach((r) => r(t)), t; } - function V(e) { + function K(e) { return e[d].value; } - function P(e, t) { - return e[d].listeners.add(t); + function D(e, t) { + if (e[d]) + return e[d].listeners.add(t); } - function F(e, t) { - return e[d].listeners.delete(t); + function $(e, t) { + if (e[d]) + return e[d].listeners.delete(t); } // src/signals.js - j(z); + N(F); globalThis.dde= { - S: g, - assign: y, - classListDeclarative: $, - createElement: te, - el: te, - empty: ne, + S: m, + assign: w, + classListDeclarative: k, + createElement: ne, + dispatchEvent: ce, + el: ne, + empty: re, isSignal: C, - namespace: ee, - on: M, - registerReactivity: j + namespace: te, + on: H, + registerReactivity: N }; })(); \ No newline at end of file diff --git a/dist/dde.js b/dist/dde.js index f748edc..61581fd 100644 --- a/dist/dde.js +++ b/dist/dde.js @@ -1,246 +1,264 @@ //deka-dom-el library is available via global namespace `dde` (()=> { // src/helpers.js - function N(e) { + function j(e) { let t = typeof e; return t !== "object" ? t : e === null ? "null" : Object.prototype.toString.call(e); } + function w(e, t) { + if (!e || !(e instanceof AbortSignal)) + return !0; + if (!e.aborted) + return e.addEventListener("abort", t), function() { + e.removeEventListener("abort", t); + }; + } // src/signals-common.js - var p = { + var l = { isTextContent(e) { - return N(e) !== "[object Object]"; + return j(e) !== "[object Object]"; }, - processReactiveAttribute(e, t, r, n) { - return r; + processReactiveAttribute(e, t, n, r) { + return n; } }; function D(e, t = !0) { - return t ? Object.assign(p, e) : (Object.setPrototypeOf(e, p), e); + return t ? Object.assign(l, e) : (Object.setPrototypeOf(e, l), e); } - function w(e) { - return p.isPrototypeOf(e) && e !== p ? e : p; + function C(e) { + return l.isPrototypeOf(e) && e !== l ? e : l; } // src/dom.js - var E = "html"; - function z(e) { - return E = e === "svg" ? "http://www.w3.org/2000/svg" : e, { + var m = "html"; + function F(e) { + return m = e === "svg" ? "http://www.w3.org/2000/svg" : e, { append(t) { - return E = "html", t; + return m = "html", t; } }; } - function F(e, t, ...r) { - let n = w(this), i; - switch (n.isTextContent(t) && (t = { textContent: t }), !0) { - case typeof e == "function": - i = e(t || void 0); + function I(e, t, ...n) { + let r = C(this), c; + switch (r.isTextContent(t) && (t = { textContent: t }), !0) { + case typeof e == "function": { + c = e(t || void 0, (s) => s ? (n.unshift(s), void 0) : c); break; + } case e === "#text": - i = x(document.createTextNode(""), t); + c = x(document.createTextNode(""), t); break; case e === "<>": - i = x(document.createDocumentFragment(), t); + c = x(document.createDocumentFragment(), t); break; - case E !== "html": - i = x(document.createElementNS(E, e), t); + case m !== "html": + c = x(document.createElementNS(m, e), t); break; - case !i: - i = x(document.createElement(e), t); + case !c: + c = x(document.createElement(e), t); } - return r.forEach((d) => d(i)), i; + return n.forEach((a) => a(c)), c; } var h = new Map(JSON.parse('[["#text,textContent",true],["HTMLElement,textContent",true],["HTMLElement,className",true]]')); function x(e, ...t) { - let r = w(this); + let n = C(this); if (!t.length) return e; - let n = e instanceof SVGElement, i = (n ? M : j).bind(null, e, "Attribute"); - return Object.entries(Object.assign({}, ...t)).forEach(function d([u, f]) { - f = r.processReactiveAttribute(e, u, f, d); - let [l] = u; - if (l === "=") - return i(u.slice(1), f); - if (l === ".") - return C(e, u.slice(1), f); + let r = e instanceof SVGElement, c = (r ? S : y).bind(null, e, "Attribute"); + return Object.entries(Object.assign({}, ...t)).forEach(function a([s, f]) { + f = n.processReactiveAttribute(e, s, f, a); + let [p] = s; + if (p === "=") + return c(s.slice(1), f); + if (p === ".") + return L(e, s.slice(1), f); if (typeof f == "object") - switch (u) { + switch (s) { case "style": - return m(f, j.bind(null, e.style, "Property")); + return E(f, y.bind(null, e.style, "Property")); case "dataset": - return m(f, C.bind(null, e.dataset)); + return E(f, L.bind(null, e.dataset)); case "ariaset": - return m(f, (g, b) => i("aria-" + g, b)); + return E(f, (g, b) => c("aria-" + g, b)); case "classList": return R(e, f); default: - return Reflect.set(e, u, f); + return Reflect.set(e, s, f); } - if (/(aria|data)([A-Z])/.test(u)) - return u = u.replace(/([a-z])([A-Z])/g, "$1-$2").toLowerCase(), i(u, f); - switch (u) { + if (/(aria|data)([A-Z])/.test(s)) + return s = s.replace(/([a-z])([A-Z])/g, "$1-$2").toLowerCase(), c(s, f); + switch (s) { case "href": - return i(u, f); + return c(s, f); case "xlink:href": - return i(u, f, "http://www.w3.org/1999/xlink"); + return c(s, f, "http://www.w3.org/1999/xlink"); case "textContent": - if (!n) + if (!r) break; return e.appendChild(document.createTextNode(f)); } - return A(e, u) ? C(e, u, f) : i(u, f); + return M(e, s) ? L(e, s, f) : c(s, f); }), e; } function R(e, t) { - return typeof t != "object" || m( + return typeof t != "object" || E( t, - (r, n) => e.classList.toggle(r, n === -1 ? void 0 : !!n) + (n, r) => e.classList.toggle(n, r === -1 ? void 0 : !!r) ), e; } - function I(e) { + function U(e) { return Array.from(e.children).forEach((t) => t.remove()), e; } - function A(e, t) { - let r = "HTMLElement," + t; - if (e instanceof HTMLElement && h.has(r)) - return h.get(r); - let n = e.nodeName + "," + t; - if (h.has(n)) + function M(e, t) { + let n = "HTMLElement," + t; + if (e instanceof HTMLElement && h.has(n)) return h.get(n); - let [i, d, u] = y(e, t), f = !L(i.set); - return (!f || d) && h.set(u === HTMLElement.prototype ? r : n, f), f; + let r = e.nodeName + "," + t; + if (h.has(r)) + return h.get(r); + let [c, a, s] = A(e, t), f = !N(c.set); + return (!f || a) && h.set(s === HTMLElement.prototype ? n : r, f), f; } - function y(e, t, r = 0) { + function A(e, t, n = 0) { if (e = Object.getPrototypeOf(e), !e) - return [{}, r, e]; - let n = Object.getOwnPropertyDescriptor(e, t); - return n ? [n, r, e] : y(e, t, r + 1); + return [{}, n, e]; + let r = Object.getOwnPropertyDescriptor(e, t); + return r ? [r, n, e] : A(e, t, n + 1); } - function m(e, t) { - return Object.entries(e).forEach(([r, n]) => t(r, n)); + function E(e, t) { + return Object.entries(e).forEach(([n, r]) => t(n, r)); } - function L(e) { + function N(e) { return typeof e > "u"; } - function j(e, t, r, n) { - return e[(L(n) ? "remove" : "set") + t](r, n); + function y(e, t, n, r) { + return e[(N(r) ? "remove" : "set") + t](n, r); } - function M(e, t, r, n, i = null) { - return e[(L(n) ? "remove" : "set") + t + "NS"](i, r, n); + function S(e, t, n, r, c = null) { + return e[(N(r) ? "remove" : "set") + t + "NS"](c, n, r); } - function C(e, t, r) { - return Reflect.set(e, t, r); + function L(e, t, n) { + return Reflect.set(e, t, n); } // src/events.js - function T(e, t, r) { - return (n) => (n.addEventListener(e, t, r), n); + function $(e, t, ...n) { + let r = n.length ? new CustomEvent(t, { detail: n[0] }) : new Event(t); + return e.dispatchEvent(r); } - var O = _(); + function T(e, t, n) { + return function(c) { + return c.addEventListener(e, t, n), c; + }; + } + var v = _(); T.connected = function(e, t) { - return function(n) { - O.onConnected(n, e), t && t.signal && t.signal.addEventListener("abort", () => O.offConnected(n, e)); + return function(r) { + return w(t && t.signal, () => v.offConnected(r, e)) && v.onConnected(r, e), r; }; }; T.disconnected = function(e, t) { - return function(n) { - O.onDisconnected(n, e), t && t.signal && t.signal.addEventListener("abort", () => O.offDisconnected(n, e)); + return function(r) { + return w(t && t.signal, () => v.offDisconnected(r, e)) && v.onDisconnected(r, e), r; }; }; function _() { - let e = /* @__PURE__ */ new Map(), t = !1, r = new MutationObserver(function(o) { - for (let c of o) - if (c.type === "childList") { - if (g(c.addedNodes, !0)) { - u(); + let e = /* @__PURE__ */ new Map(), t = !1, n = new MutationObserver(function(o) { + for (let i of o) + if (i.type === "childList") { + if (g(i.addedNodes, !0)) { + s(); continue; } - b(c.removedNodes, !0) && u(); + b(i.removedNodes, !0) && s(); } }); return { - onConnected(o, c) { - d(), i(o).connected.push(c); + onConnected(o, i) { + a(), c(o).connected.push(i); }, - offConnected(o, c) { + offConnected(o, i) { if (!e.has(o)) return; - let s = e.get(o), a = s.connected; - a.splice(a.indexOf(c), 1), n(o, s); + let u = e.get(o), d = u.connected; + d.splice(d.indexOf(i), 1), r(o, u); }, - onDisconnected(o, c) { - d(), i(o).disconnected.push(c); + onDisconnected(o, i) { + a(), c(o).disconnected.push(i); }, - offDisconnected(o, c) { + offDisconnected(o, i) { if (!e.has(o)) return; - let s = e.get(o), a = s.disconnected; - a.splice(a.indexOf(c), 1), n(o, s); + let u = e.get(o), d = u.disconnected; + d.splice(d.indexOf(i), 1), r(o, u); } }; - function n(o, c) { - c.connected.length || c.disconnect.length || (e.delete(o), u()); + function r(o, i) { + i.connected.length || i.disconnected.length || (e.delete(o), s()); } - function i(o) { + function c(o) { if (e.has(o)) return e.get(o); - let c = { connected: [], disconnected: [] }; - return e.set(o, c), c; + let i = { connected: [], disconnected: [] }; + return e.set(o, i), i; } - function d() { - t || (t = !0, r.observe(document.body, { childList: !0, subtree: !0 })); + function a() { + t || (t = !0, n.observe(document.body, { childList: !0, subtree: !0 })); } - function u() { - !t || e.size || (t = !1, r.disconnect()); + function s() { + !t || e.size || (t = !1, n.disconnect()); } function f() { return new Promise(function(o) { (requestIdleCallback || requestAnimationFrame)(o); }); } - async function l(o) { + async function p(o) { e.size > 30 && await f(); - let c = []; + let i = []; if (!(o instanceof Node)) - return c; - for (let s of e.keys()) - s === o || !(s instanceof Node) || o.contains(s) && c.push(s); - return c; + return i; + for (let u of e.keys()) + u === o || !(u instanceof Node) || o.contains(u) && i.push(u); + return i; } - function g(o, c) { - for (let s of o) { - if (c && l(s).then(g), !e.has(s)) - return !1; - let a = e.get(s); - return a.connected.forEach((v) => v(s)), a.connected.length = 0, a.disconnected.length || e.delete(s), !0; + function g(o, i) { + for (let u of o) { + if (i && p(u).then(g), !e.has(u)) + continue; + let d = e.get(u); + return d.connected.forEach((O) => O(u)), d.connected.length = 0, d.disconnected.length || e.delete(u), !0; } + return !1; } - function b(o, c) { - for (let s of o) { - if (c && l(s).then(b), !e.has(s)) - return !1; - let a = e.get(s); - return a.disconnected.forEach((v) => v(s)), a.connected.length = 0, a.disconnected.length = 0, e.delete(s), !0; + function b(o, i) { + for (let u of o) { + if (i && p(u).then(b), !e.has(u)) + continue; + let d = e.get(u); + return d.disconnected.forEach((O) => O(u)), d.connected.length = 0, d.disconnected.length = 0, e.delete(u), !0; } + return !1; } } // index.js [HTMLElement, DocumentFragment].forEach((e) => { let { append: t } = e.prototype; - e.prototype.append = function(...r) { - return t.apply(this, r), this; + e.prototype.append = function(...n) { + return t.apply(this, n), this; }; }); globalThis.dde= { assign: x, classListDeclarative: R, - createElement: F, - el: F, - empty: I, - namespace: z, + createElement: I, + dispatchEvent: $, + el: I, + empty: U, + namespace: F, on: T, registerReactivity: D }; diff --git a/dist/esm-with-signals.js b/dist/esm-with-signals.js index 5af4c59..3832b63 100644 --- a/dist/esm-with-signals.js +++ b/dist/esm-with-signals.js @@ -1,226 +1,243 @@ // src/helpers.js -function m(e) { +function g(e) { let t = typeof e; return t !== "object" ? t : e === null ? "null" : Object.prototype.toString.call(e); } +function j(e, t) { + if (!e || !(e instanceof AbortSignal)) + return !0; + if (!e.aborted) + return e.addEventListener("abort", t), function() { + e.removeEventListener("abort", t); + }; +} // src/signals-common.js var b = { isTextContent(e) { - return m(e) !== "[object Object]"; + return g(e) !== "[object Object]"; }, processReactiveAttribute(e, t, n, r) { return n; } }; -function j(e, t = !0) { +function N(e, t = !0) { return t ? Object.assign(b, e) : (Object.setPrototypeOf(e, b), e); } -function N(e) { +function A(e) { return b.isPrototypeOf(e) && e !== b ? e : b; } // src/dom.js -var v = "html"; -function ee(e) { - return v = e === "svg" ? "http://www.w3.org/2000/svg" : e, { +var y = "html"; +function te(e) { + return y = e === "svg" ? "http://www.w3.org/2000/svg" : e, { append(t) { - return v = "html", t; + return y = "html", t; } }; } -function te(e, t, ...n) { - let r = N(this), o; +function ne(e, t, ...n) { + let r = A(this), o; switch (r.isTextContent(t) && (t = { textContent: t }), !0) { - case typeof e == "function": - o = e(t || void 0); + case typeof e == "function": { + o = e(t || void 0, (s) => s ? (n.unshift(s), void 0) : o); break; + } case e === "#text": - o = y(document.createTextNode(""), t); + o = w(document.createTextNode(""), t); break; case e === "<>": - o = y(document.createDocumentFragment(), t); + o = w(document.createDocumentFragment(), t); break; - case v !== "html": - o = y(document.createElementNS(v, e), t); + case y !== "html": + o = w(document.createElementNS(y, e), t); break; case !o: - o = y(document.createElement(e), t); + o = w(document.createElement(e), t); } return n.forEach((a) => a(o)), o; } var x = new Map(JSON.parse('[["#text,textContent",true],["HTMLElement,textContent",true],["HTMLElement,className",true]]')); -function y(e, ...t) { - let n = N(this); +function w(e, ...t) { + let n = A(this); if (!t.length) return e; - let r = e instanceof SVGElement, o = (r ? q : D).bind(null, e, "Attribute"); - return Object.entries(Object.assign({}, ...t)).forEach(function a([f, s]) { - s = n.processReactiveAttribute(e, f, s, a); - let [h] = f; + let r = e instanceof SVGElement, o = (r ? J : T).bind(null, e, "Attribute"); + return Object.entries(Object.assign({}, ...t)).forEach(function a([s, i]) { + i = n.processReactiveAttribute(e, s, i, a); + let [h] = s; if (h === "=") - return o(f.slice(1), s); + return o(s.slice(1), i); if (h === ".") - return _(e, f.slice(1), s); - if (typeof s == "object") - switch (f) { + return _(e, s.slice(1), i); + if (typeof i == "object") + switch (s) { case "style": - return w(s, D.bind(null, e.style, "Property")); + return O(i, T.bind(null, e.style, "Property")); case "dataset": - return w(s, _.bind(null, e.dataset)); + return O(i, _.bind(null, e.dataset)); case "ariaset": - return w(s, (E, O) => o("aria-" + E, O)); + return O(i, (E, v) => o("aria-" + E, v)); case "classList": - return $(e, s); + return k(e, i); default: - return Reflect.set(e, f, s); + return Reflect.set(e, s, i); } - if (/(aria|data)([A-Z])/.test(f)) - return f = f.replace(/([a-z])([A-Z])/g, "$1-$2").toLowerCase(), o(f, s); - switch (f) { + if (/(aria|data)([A-Z])/.test(s)) + return s = s.replace(/([a-z])([A-Z])/g, "$1-$2").toLowerCase(), o(s, i); + switch (s) { case "href": - return o(f, s); + return o(s, i); case "xlink:href": - return o(f, s, "http://www.w3.org/1999/xlink"); + return o(s, i, "http://www.w3.org/1999/xlink"); case "textContent": if (!r) break; - return e.appendChild(document.createTextNode(s)); + return e.appendChild(document.createTextNode(i)); } - return k(e, f) ? _(e, f, s) : o(f, s); + return q(e, s) ? _(e, s, i) : o(s, i); }), e; } -function $(e, t) { - return typeof t != "object" || w( +function k(e, t) { + return typeof t != "object" || O( t, (n, r) => e.classList.toggle(n, r === -1 ? void 0 : !!r) ), e; } -function ne(e) { +function re(e) { return Array.from(e.children).forEach((t) => t.remove()), e; } -function k(e, t) { +function q(e, t) { let n = "HTMLElement," + t; if (e instanceof HTMLElement && x.has(n)) return x.get(n); let r = e.nodeName + "," + t; if (x.has(r)) return x.get(r); - let [o, a, f] = T(e, t), s = !A(o.set); - return (!s || a) && x.set(f === HTMLElement.prototype ? n : r, s), s; + let [o, a, s] = M(e, t), i = !P(o.set); + return (!i || a) && x.set(s === HTMLElement.prototype ? n : r, i), i; } -function T(e, t, n = 0) { +function M(e, t, n = 0) { if (e = Object.getPrototypeOf(e), !e) return [{}, n, e]; let r = Object.getOwnPropertyDescriptor(e, t); - return r ? [r, n, e] : T(e, t, n + 1); + return r ? [r, n, e] : M(e, t, n + 1); } -function w(e, t) { +function O(e, t) { return Object.entries(e).forEach(([n, r]) => t(n, r)); } -function A(e) { +function P(e) { return typeof e > "u"; } -function D(e, t, n, r) { - return e[(A(r) ? "remove" : "set") + t](n, r); +function T(e, t, n, r) { + return e[(P(r) ? "remove" : "set") + t](n, r); } -function q(e, t, n, r, o = null) { - return e[(A(r) ? "remove" : "set") + t + "NS"](o, n, r); +function J(e, t, n, r, o = null) { + return e[(P(r) ? "remove" : "set") + t + "NS"](o, n, r); } function _(e, t, n) { return Reflect.set(e, t, n); } // src/events.js -function M(e, t, n) { - return (r) => (r.addEventListener(e, t, n), r); +function ce(e, t, ...n) { + let r = n.length ? new CustomEvent(t, { detail: n[0] }) : new Event(t); + return e.dispatchEvent(r); } -var S = J(); -M.connected = function(e, t) { +function H(e, t, n) { + return function(o) { + return o.addEventListener(e, t, n), o; + }; +} +var S = W(); +H.connected = function(e, t) { return function(r) { - S.onConnected(r, e), t && t.signal && t.signal.addEventListener("abort", () => S.offConnected(r, e)); + return j(t && t.signal, () => S.offConnected(r, e)) && S.onConnected(r, e), r; }; }; -M.disconnected = function(e, t) { +H.disconnected = function(e, t) { return function(r) { - S.onDisconnected(r, e), t && t.signal && t.signal.addEventListener("abort", () => S.offDisconnected(r, e)); + return j(t && t.signal, () => S.offDisconnected(r, e)) && S.onDisconnected(r, e), r; }; }; -function J() { +function W() { let e = /* @__PURE__ */ new Map(), t = !1, n = new MutationObserver(function(c) { - for (let i of c) - if (i.type === "childList") { - if (E(i.addedNodes, !0)) { - f(); + for (let f of c) + if (f.type === "childList") { + if (E(f.addedNodes, !0)) { + s(); continue; } - O(i.removedNodes, !0) && f(); + v(f.removedNodes, !0) && s(); } }); return { - onConnected(c, i) { - a(), o(c).connected.push(i); + onConnected(c, f) { + a(), o(c).connected.push(f); }, - offConnected(c, i) { + offConnected(c, f) { if (!e.has(c)) return; let u = e.get(c), l = u.connected; - l.splice(l.indexOf(i), 1), r(c, u); + l.splice(l.indexOf(f), 1), r(c, u); }, - onDisconnected(c, i) { - a(), o(c).disconnected.push(i); + onDisconnected(c, f) { + a(), o(c).disconnected.push(f); }, - offDisconnected(c, i) { + offDisconnected(c, f) { if (!e.has(c)) return; let u = e.get(c), l = u.disconnected; - l.splice(l.indexOf(i), 1), r(c, u); + l.splice(l.indexOf(f), 1), r(c, u); } }; - function r(c, i) { - i.connected.length || i.disconnect.length || (e.delete(c), f()); + function r(c, f) { + f.connected.length || f.disconnected.length || (e.delete(c), s()); } function o(c) { if (e.has(c)) return e.get(c); - let i = { connected: [], disconnected: [] }; - return e.set(c, i), i; + let f = { connected: [], disconnected: [] }; + return e.set(c, f), f; } function a() { t || (t = !0, n.observe(document.body, { childList: !0, subtree: !0 })); } - function f() { + function s() { !t || e.size || (t = !1, n.disconnect()); } - function s() { + function i() { return new Promise(function(c) { (requestIdleCallback || requestAnimationFrame)(c); }); } async function h(c) { - e.size > 30 && await s(); - let i = []; + e.size > 30 && await i(); + let f = []; if (!(c instanceof Node)) - return i; + return f; for (let u of e.keys()) - u === c || !(u instanceof Node) || c.contains(u) && i.push(u); - return i; + u === c || !(u instanceof Node) || c.contains(u) && f.push(u); + return f; } - function E(c, i) { + function E(c, f) { for (let u of c) { - if (i && h(u).then(E), !e.has(u)) - return !1; + if (f && h(u).then(E), !e.has(u)) + continue; let l = e.get(u); return l.connected.forEach((L) => L(u)), l.connected.length = 0, l.disconnected.length || e.delete(u), !0; } + return !1; } - function O(c, i) { + function v(c, f) { for (let u of c) { - if (i && h(u).then(O), !e.has(u)) - return !1; + if (f && h(u).then(v), !e.has(u)) + continue; let l = e.get(u); return l.disconnected.forEach((L) => L(u)), l.connected.length = 0, l.disconnected.length = 0, e.delete(u), !0; } + return !1; } } @@ -242,15 +259,15 @@ function C(e) { } } var p = /* @__PURE__ */ new WeakMap(); -function g(e, t) { +function m(e, t) { if (typeof e != "function") - return H(e, t); + return z(e, t); if (C(e)) return e; - let n = H(""), r = () => n(e()); + let n = z(""), r = () => n(e()); return p.set(r, /* @__PURE__ */ new Set([n])), Z(r), n; } -g.action = function(e, t, ...n) { +m.action = function(e, t, ...n) { let r = e[d], { actions: o } = r; if (!o || !Reflect.has(o, t)) throw new Error(`'${e}' has no action with name '${t}'!`); @@ -258,22 +275,22 @@ g.action = function(e, t, ...n) { return Reflect.deleteProperty(r, "skip"); r.listeners.forEach((a) => a(r.value)); }; -g.on = function e(t, n, r = {}) { +m.on = function e(t, n, r = {}) { let { signal: o } = r; if (!(o && o.aborted)) { if (Array.isArray(t)) return t.forEach((a) => e(a, n, r)); - P(t, n), o && o.addEventListener("abort", () => F(t, n)); + D(t, n), o && o.addEventListener("abort", () => $(t, n)); } }; -g.symbols = { +m.symbols = { signal: d, onclear: Symbol.for("Signal.onclear") }; -g.clear = function(...e) { +m.clear = function(...e) { for (let n of e) { Reflect.deleteProperty(n, "toJSON"); - let r = n[d], { onclear: o } = g.symbols; + let r = n[d], { onclear: o } = m.symbols; r.actions && r.actions[o] && r.actions[o].call(r), t(n, r), Reflect.deleteProperty(n, d); } function t(n, r) { @@ -281,48 +298,48 @@ g.clear = function(...e) { if (r.listeners.delete(o), !p.has(o)) return; let a = p.get(o); - a.delete(n), !(a.size > 1) && (g.clear(...a), p.delete(o)); + a.delete(n), !(a.size > 1) && (m.clear(...a), p.delete(o)); }); } }; -g.el = function(e, t) { +m.el = function(e, t) { let n = document.createComment("<#reactive>"), r = document.createComment(""), o = document.createDocumentFragment(); o.append(n, r); - let a = (f) => { + let a = (s) => { if (!n.parentNode || !r.parentNode) - return F(e, a); - let s = t(f); - Array.isArray(s) || (s = [s]); + return $(e, a); + let i = t(s); + Array.isArray(i) || (i = [i]); let h = n; for (; (h = n.nextSibling) !== r; ) h.remove(); - n.after(...s); + n.after(...i); }; - return P(e, a), a(e()), o; + return D(e, a), a(e()), o; }; -var z = { +var F = { isTextContent(e) { - return m(e) === "string" || C(e) && m(V(e)) === "string"; + return g(e) === "string" || C(e) && g(K(e)) === "string"; }, processReactiveAttribute(e, t, n, r) { - return C(n) ? (P(n, (o) => r([t, o])), n()) : n; + return C(n) ? (D(n, (o) => r([t, o])), n()) : n; } }; -function H(e, t) { - let n = (...r) => r.length ? U(n, r[0]) : G(n); - return I(n, e, t); +function z(e, t) { + let n = (...r) => r.length ? V(n, r[0]) : G(n); + return U(n, e, t); } -var W = Object.assign(/* @__PURE__ */ Object.create(null), { +var I = Object.assign(/* @__PURE__ */ Object.create(null), { stopPropagation() { this.skip = !0; } }); -function I(e, t, n) { - return m(n) !== "[object Object]" && (n = {}), e[d] = { +function U(e, t, n) { + return g(n) !== "[object Object]" && (n = {}), e[d] = { value: t, actions: n, listeners: /* @__PURE__ */ new Set() - }, e.toJSON = () => e(), Object.setPrototypeOf(e[d], W), e; + }, e.toJSON = () => e(), Object.setPrototypeOf(e[d], I), e; } var R = []; function Z(e) { @@ -340,34 +357,37 @@ function G(e) { let { value: t, listeners: n } = e[d], r = B(); return r && n.add(r), p.has(r) && p.get(r).add(e), t; } -function U(e, t) { +function V(e, t) { if (!e[d]) return; let n = e[d]; if (n.value !== t) return n.value = t, n.listeners.forEach((r) => r(t)), t; } -function V(e) { +function K(e) { return e[d].value; } -function P(e, t) { - return e[d].listeners.add(t); +function D(e, t) { + if (e[d]) + return e[d].listeners.add(t); } -function F(e, t) { - return e[d].listeners.delete(t); +function $(e, t) { + if (e[d]) + return e[d].listeners.delete(t); } // src/signals.js -j(z); +N(F); export { - g as S, - y as assign, - $ as classListDeclarative, - te as createElement, - te as el, - ne as empty, + m as S, + w as assign, + k as classListDeclarative, + ne as createElement, + ce as dispatchEvent, + ne as el, + re as empty, C as isSignal, - ee as namespace, - M as on, - j as registerReactivity + te as namespace, + H as on, + N as registerReactivity }; diff --git a/dist/esm.js b/dist/esm.js index e4f1b4a..64176bf 100644 --- a/dist/esm.js +++ b/dist/esm.js @@ -1,243 +1,261 @@ // src/helpers.js -function N(e) { +function j(e) { let t = typeof e; return t !== "object" ? t : e === null ? "null" : Object.prototype.toString.call(e); } +function w(e, t) { + if (!e || !(e instanceof AbortSignal)) + return !0; + if (!e.aborted) + return e.addEventListener("abort", t), function() { + e.removeEventListener("abort", t); + }; +} // src/signals-common.js -var p = { +var l = { isTextContent(e) { - return N(e) !== "[object Object]"; + return j(e) !== "[object Object]"; }, - processReactiveAttribute(e, t, r, n) { - return r; + processReactiveAttribute(e, t, n, r) { + return n; } }; function D(e, t = !0) { - return t ? Object.assign(p, e) : (Object.setPrototypeOf(e, p), e); + return t ? Object.assign(l, e) : (Object.setPrototypeOf(e, l), e); } -function w(e) { - return p.isPrototypeOf(e) && e !== p ? e : p; +function C(e) { + return l.isPrototypeOf(e) && e !== l ? e : l; } // src/dom.js -var E = "html"; -function z(e) { - return E = e === "svg" ? "http://www.w3.org/2000/svg" : e, { +var m = "html"; +function F(e) { + return m = e === "svg" ? "http://www.w3.org/2000/svg" : e, { append(t) { - return E = "html", t; + return m = "html", t; } }; } -function F(e, t, ...r) { - let n = w(this), i; - switch (n.isTextContent(t) && (t = { textContent: t }), !0) { - case typeof e == "function": - i = e(t || void 0); +function I(e, t, ...n) { + let r = C(this), c; + switch (r.isTextContent(t) && (t = { textContent: t }), !0) { + case typeof e == "function": { + c = e(t || void 0, (s) => s ? (n.unshift(s), void 0) : c); break; + } case e === "#text": - i = x(document.createTextNode(""), t); + c = x(document.createTextNode(""), t); break; case e === "<>": - i = x(document.createDocumentFragment(), t); + c = x(document.createDocumentFragment(), t); break; - case E !== "html": - i = x(document.createElementNS(E, e), t); + case m !== "html": + c = x(document.createElementNS(m, e), t); break; - case !i: - i = x(document.createElement(e), t); + case !c: + c = x(document.createElement(e), t); } - return r.forEach((d) => d(i)), i; + return n.forEach((a) => a(c)), c; } var h = new Map(JSON.parse('[["#text,textContent",true],["HTMLElement,textContent",true],["HTMLElement,className",true]]')); function x(e, ...t) { - let r = w(this); + let n = C(this); if (!t.length) return e; - let n = e instanceof SVGElement, i = (n ? M : j).bind(null, e, "Attribute"); - return Object.entries(Object.assign({}, ...t)).forEach(function d([u, f]) { - f = r.processReactiveAttribute(e, u, f, d); - let [l] = u; - if (l === "=") - return i(u.slice(1), f); - if (l === ".") - return C(e, u.slice(1), f); + let r = e instanceof SVGElement, c = (r ? S : y).bind(null, e, "Attribute"); + return Object.entries(Object.assign({}, ...t)).forEach(function a([s, f]) { + f = n.processReactiveAttribute(e, s, f, a); + let [p] = s; + if (p === "=") + return c(s.slice(1), f); + if (p === ".") + return L(e, s.slice(1), f); if (typeof f == "object") - switch (u) { + switch (s) { case "style": - return m(f, j.bind(null, e.style, "Property")); + return E(f, y.bind(null, e.style, "Property")); case "dataset": - return m(f, C.bind(null, e.dataset)); + return E(f, L.bind(null, e.dataset)); case "ariaset": - return m(f, (g, b) => i("aria-" + g, b)); + return E(f, (g, b) => c("aria-" + g, b)); case "classList": return R(e, f); default: - return Reflect.set(e, u, f); + return Reflect.set(e, s, f); } - if (/(aria|data)([A-Z])/.test(u)) - return u = u.replace(/([a-z])([A-Z])/g, "$1-$2").toLowerCase(), i(u, f); - switch (u) { + if (/(aria|data)([A-Z])/.test(s)) + return s = s.replace(/([a-z])([A-Z])/g, "$1-$2").toLowerCase(), c(s, f); + switch (s) { case "href": - return i(u, f); + return c(s, f); case "xlink:href": - return i(u, f, "http://www.w3.org/1999/xlink"); + return c(s, f, "http://www.w3.org/1999/xlink"); case "textContent": - if (!n) + if (!r) break; return e.appendChild(document.createTextNode(f)); } - return A(e, u) ? C(e, u, f) : i(u, f); + return M(e, s) ? L(e, s, f) : c(s, f); }), e; } function R(e, t) { - return typeof t != "object" || m( + return typeof t != "object" || E( t, - (r, n) => e.classList.toggle(r, n === -1 ? void 0 : !!n) + (n, r) => e.classList.toggle(n, r === -1 ? void 0 : !!r) ), e; } -function I(e) { +function U(e) { return Array.from(e.children).forEach((t) => t.remove()), e; } -function A(e, t) { - let r = "HTMLElement," + t; - if (e instanceof HTMLElement && h.has(r)) - return h.get(r); - let n = e.nodeName + "," + t; - if (h.has(n)) +function M(e, t) { + let n = "HTMLElement," + t; + if (e instanceof HTMLElement && h.has(n)) return h.get(n); - let [i, d, u] = y(e, t), f = !L(i.set); - return (!f || d) && h.set(u === HTMLElement.prototype ? r : n, f), f; + let r = e.nodeName + "," + t; + if (h.has(r)) + return h.get(r); + let [c, a, s] = A(e, t), f = !N(c.set); + return (!f || a) && h.set(s === HTMLElement.prototype ? n : r, f), f; } -function y(e, t, r = 0) { +function A(e, t, n = 0) { if (e = Object.getPrototypeOf(e), !e) - return [{}, r, e]; - let n = Object.getOwnPropertyDescriptor(e, t); - return n ? [n, r, e] : y(e, t, r + 1); + return [{}, n, e]; + let r = Object.getOwnPropertyDescriptor(e, t); + return r ? [r, n, e] : A(e, t, n + 1); } -function m(e, t) { - return Object.entries(e).forEach(([r, n]) => t(r, n)); +function E(e, t) { + return Object.entries(e).forEach(([n, r]) => t(n, r)); } -function L(e) { +function N(e) { return typeof e > "u"; } -function j(e, t, r, n) { - return e[(L(n) ? "remove" : "set") + t](r, n); +function y(e, t, n, r) { + return e[(N(r) ? "remove" : "set") + t](n, r); } -function M(e, t, r, n, i = null) { - return e[(L(n) ? "remove" : "set") + t + "NS"](i, r, n); +function S(e, t, n, r, c = null) { + return e[(N(r) ? "remove" : "set") + t + "NS"](c, n, r); } -function C(e, t, r) { - return Reflect.set(e, t, r); +function L(e, t, n) { + return Reflect.set(e, t, n); } // src/events.js -function T(e, t, r) { - return (n) => (n.addEventListener(e, t, r), n); +function $(e, t, ...n) { + let r = n.length ? new CustomEvent(t, { detail: n[0] }) : new Event(t); + return e.dispatchEvent(r); } -var O = _(); +function T(e, t, n) { + return function(c) { + return c.addEventListener(e, t, n), c; + }; +} +var v = _(); T.connected = function(e, t) { - return function(n) { - O.onConnected(n, e), t && t.signal && t.signal.addEventListener("abort", () => O.offConnected(n, e)); + return function(r) { + return w(t && t.signal, () => v.offConnected(r, e)) && v.onConnected(r, e), r; }; }; T.disconnected = function(e, t) { - return function(n) { - O.onDisconnected(n, e), t && t.signal && t.signal.addEventListener("abort", () => O.offDisconnected(n, e)); + return function(r) { + return w(t && t.signal, () => v.offDisconnected(r, e)) && v.onDisconnected(r, e), r; }; }; function _() { - let e = /* @__PURE__ */ new Map(), t = !1, r = new MutationObserver(function(o) { - for (let c of o) - if (c.type === "childList") { - if (g(c.addedNodes, !0)) { - u(); + let e = /* @__PURE__ */ new Map(), t = !1, n = new MutationObserver(function(o) { + for (let i of o) + if (i.type === "childList") { + if (g(i.addedNodes, !0)) { + s(); continue; } - b(c.removedNodes, !0) && u(); + b(i.removedNodes, !0) && s(); } }); return { - onConnected(o, c) { - d(), i(o).connected.push(c); + onConnected(o, i) { + a(), c(o).connected.push(i); }, - offConnected(o, c) { + offConnected(o, i) { if (!e.has(o)) return; - let s = e.get(o), a = s.connected; - a.splice(a.indexOf(c), 1), n(o, s); + let u = e.get(o), d = u.connected; + d.splice(d.indexOf(i), 1), r(o, u); }, - onDisconnected(o, c) { - d(), i(o).disconnected.push(c); + onDisconnected(o, i) { + a(), c(o).disconnected.push(i); }, - offDisconnected(o, c) { + offDisconnected(o, i) { if (!e.has(o)) return; - let s = e.get(o), a = s.disconnected; - a.splice(a.indexOf(c), 1), n(o, s); + let u = e.get(o), d = u.disconnected; + d.splice(d.indexOf(i), 1), r(o, u); } }; - function n(o, c) { - c.connected.length || c.disconnect.length || (e.delete(o), u()); + function r(o, i) { + i.connected.length || i.disconnected.length || (e.delete(o), s()); } - function i(o) { + function c(o) { if (e.has(o)) return e.get(o); - let c = { connected: [], disconnected: [] }; - return e.set(o, c), c; + let i = { connected: [], disconnected: [] }; + return e.set(o, i), i; } - function d() { - t || (t = !0, r.observe(document.body, { childList: !0, subtree: !0 })); + function a() { + t || (t = !0, n.observe(document.body, { childList: !0, subtree: !0 })); } - function u() { - !t || e.size || (t = !1, r.disconnect()); + function s() { + !t || e.size || (t = !1, n.disconnect()); } function f() { return new Promise(function(o) { (requestIdleCallback || requestAnimationFrame)(o); }); } - async function l(o) { + async function p(o) { e.size > 30 && await f(); - let c = []; + let i = []; if (!(o instanceof Node)) - return c; - for (let s of e.keys()) - s === o || !(s instanceof Node) || o.contains(s) && c.push(s); - return c; + return i; + for (let u of e.keys()) + u === o || !(u instanceof Node) || o.contains(u) && i.push(u); + return i; } - function g(o, c) { - for (let s of o) { - if (c && l(s).then(g), !e.has(s)) - return !1; - let a = e.get(s); - return a.connected.forEach((v) => v(s)), a.connected.length = 0, a.disconnected.length || e.delete(s), !0; + function g(o, i) { + for (let u of o) { + if (i && p(u).then(g), !e.has(u)) + continue; + let d = e.get(u); + return d.connected.forEach((O) => O(u)), d.connected.length = 0, d.disconnected.length || e.delete(u), !0; } + return !1; } - function b(o, c) { - for (let s of o) { - if (c && l(s).then(b), !e.has(s)) - return !1; - let a = e.get(s); - return a.disconnected.forEach((v) => v(s)), a.connected.length = 0, a.disconnected.length = 0, e.delete(s), !0; + function b(o, i) { + for (let u of o) { + if (i && p(u).then(b), !e.has(u)) + continue; + let d = e.get(u); + return d.disconnected.forEach((O) => O(u)), d.connected.length = 0, d.disconnected.length = 0, e.delete(u), !0; } + return !1; } } // index.js [HTMLElement, DocumentFragment].forEach((e) => { let { append: t } = e.prototype; - e.prototype.append = function(...r) { - return t.apply(this, r), this; + e.prototype.append = function(...n) { + return t.apply(this, n), this; }; }); export { x as assign, R as classListDeclarative, - F as createElement, - F as el, - I as empty, - z as namespace, + I as createElement, + $ as dispatchEvent, + I as el, + U as empty, + F as namespace, T as on, D as registerReactivity }; diff --git a/index.d.ts b/index.d.ts index 821a272..3a24036 100644 --- a/index.d.ts +++ b/index.d.ts @@ -1,7 +1,16 @@ import { Signal } from "./src/signals"; //TODO? +/** Is filled when function is succesfully called ⇒ and returns component's root element. */ +type Host= (extender?: ElementExtender)=> el | undefined; declare global { - type ddeFires= ( (...a: any[])=> any ) & { events: T }; + /** + * `ref` is filled when function is succesfully called ⇒ and returns component's root element. + * */ + type ddeComponent< + A extends Record, + R extends Element, + T extends string[] = [] + >= (attrs: A, ref: Host)=> R & { _events: T }; } type ElementTagNameMap= HTMLElementTagNameMap & SVGElementTagNameMap & { '#text': Text @@ -47,12 +56,14 @@ export function el( signal?: Signal, cb?: (a: T)=> HTMLElement | HTMLElement[] ): DocumentFragment -export function el Element>( +export function el)=> R>( fComponent: T, - attrs?: Parameters & ElementAttributes>, + attrs?: Parameters, ...extenders: ElementExtender>[] ): ReturnType +export function dispatchEvent(element: HTMLElement, name: keyof DocumentEventMap): void; +export function dispatchEvent(element: HTMLElement, name: string, data: any): void; interface On{ < EE extends ElementExtender, diff --git a/package.json b/package.json index 453bea3..bc153db 100644 --- a/package.json +++ b/package.json @@ -66,7 +66,8 @@ "maxdepth": 3, "maxcomplexity": 10, "globals": { - "requestIdleCallback": false + "requestIdleCallback": false, + "AbortSignal": false } }, "size-limit": [ diff --git a/src/dom.js b/src/dom.js index 56b4a1a..47c3c54 100644 --- a/src/dom.js +++ b/src/dom.js @@ -15,7 +15,11 @@ export function createElement(tag, attributes, ...connect){ if(s.isTextContent(attributes)) attributes= { textContent: attributes }; switch(true){ - case typeof tag==="function": el= tag(attributes || undefined); break; + case typeof tag==="function": { + const ref= c=> c ? (connect.unshift(c), undefined) : el; + el= tag(attributes || undefined, ref); + break; + } case tag==="#text": el= assign(document.createTextNode(""), attributes); break; case tag==="<>": el= assign(document.createDocumentFragment(), attributes); break; case namespace_curr!=="html": el= assign(document.createElementNS(namespace_curr, tag), attributes); break; @@ -34,7 +38,7 @@ export function assign(element, ...attributes){ const is_svg= element instanceof SVGElement; const setRemoveAttr= (is_svg ? setRemoveNS : setRemove).bind(null, element, "Attribute"); - /* jshint maxcomplexity:15 */ + /* jshint maxcomplexity:16 */ Object.entries(Object.assign({}, ...attributes)).forEach(function assignNth([ key, attr ]){ attr= s.processReactiveAttribute(element, key, attr, assignNth); const [ k ]= key; diff --git a/src/events.js b/src/events.js index 60957cb..92c8186 100644 --- a/src/events.js +++ b/src/events.js @@ -1,25 +1,31 @@ export { registerReactivity } from './signals-common.js'; +export function dispatchEvent(element, name, ...d){ + const event= d.length ? new CustomEvent(name, { detail: d[0] }) : new Event(name); + return element.dispatchEvent(event); +} export function on(event, listener, options){ - return element=> { + return function registerElement(element){ element.addEventListener(event, listener, options); return element; }; } const c_ch_o= connectionsChangesObserverConstructor(); +import { onAbort } from './helpers.js'; +//TODO: cleanUp when event before abort? on.connected= function(listener, options){ return function registerElement(element){ - c_ch_o.onConnected(element, listener); - if(options && options.signal) - options.signal.addEventListener("abort", ()=> c_ch_o.offConnected(element, listener)); + const c= onAbort(options && options.signal, ()=> c_ch_o.offConnected(element, listener)); + if(c) c_ch_o.onConnected(element, listener); + return element; }; }; on.disconnected= function(listener, options){ return function registerElement(element){ - c_ch_o.onDisconnected(element, listener); - if(options && options.signal) - options.signal.addEventListener("abort", ()=> c_ch_o.offDisconnected(element, listener)); + const c= onAbort(options && options.signal, ()=> c_ch_o.offDisconnected(element, listener)); + if(c) c_ch_o.onDisconnected(element, listener); + return element; }; }; @@ -64,7 +70,7 @@ function connectionsChangesObserverConstructor(){ } }; function cleanWhenOff(element, ls){ - if(ls.connected.length || ls.disconnect.length) + if(ls.connected.length || ls.disconnected.length) return; store.delete(element); stop(); @@ -104,7 +110,7 @@ function connectionsChangesObserverConstructor(){ function observerAdded(addedNodes, is_root){ for(const element of addedNodes){ if(is_root) collectChildren(element).then(observerAdded); - if(!store.has(element)) return false; + if(!store.has(element)) continue; const ls= store.get(element); ls.connected.forEach(listener=> listener(element)); @@ -112,11 +118,12 @@ function connectionsChangesObserverConstructor(){ if(!ls.disconnected.length) store.delete(element); return true; } + return false; } function observerRemoved(removedNodes, is_root){ for(const element of removedNodes){ if(is_root) collectChildren(element).then(observerRemoved); - if(!store.has(element)) return false; + if(!store.has(element)) continue; const ls= store.get(element); ls.disconnected.forEach(listener=> listener(element)); @@ -126,5 +133,6 @@ function connectionsChangesObserverConstructor(){ store.delete(element); return true; } + return false; } } diff --git a/src/helpers.js b/src/helpers.js index d50c83f..f72083f 100644 --- a/src/helpers.js +++ b/src/helpers.js @@ -4,3 +4,13 @@ export function typeOf(v){ if(v===null) return "null"; return Object.prototype.toString.call(v); } +export function onAbort(signal, listener){ + if(!signal || !(signal instanceof AbortSignal)) + return true; + if(signal.aborted) + return; + signal.addEventListener("abort", listener); + return function cleanUp(){ + signal.removeEventListener("abort", listener); + }; +} diff --git a/src/signals-lib.js b/src/signals-lib.js index 231ab1a..f1d5729 100644 --- a/src/signals-lib.js +++ b/src/signals-lib.js @@ -152,8 +152,10 @@ function valueOfSignal(signal){ return signal[mark].value; } function addSignalListener(signal, listener){ + if(!signal[mark]) return; return signal[mark].listeners.add(listener); } function removeSignalListener(signal, listener){ + if(!signal[mark]) return; return signal[mark].listeners.delete(listener); } diff --git a/src/signals.d.ts b/src/signals.d.ts index ac17832..7632cc6 100644 --- a/src/signals.d.ts +++ b/src/signals.d.ts @@ -44,6 +44,6 @@ interface S { } export const S: S; declare global { - type ddeSignal= Signal; + type ddeSignal= Signal; type ddeActions= Actions } diff --git a/test/components/todosComponent.js b/test/components/todosComponent.js index 37685fc..0ee48bb 100644 --- a/test/components/todosComponent.js +++ b/test/components/todosComponent.js @@ -1,4 +1,4 @@ -import { style, el, on, S } from '../exports.js'; +import { style, el, dispatchEvent, on, S } from '../exports.js'; const className= style.host(todosComponent).css` :host{ display: flex; @@ -24,12 +24,10 @@ export function todosComponent({ todos= [ "Task A" ] }= {}){ todos.forEach(v=> S.action(todosS, "add", v)); const name= "todoName"; const onsubmitAdd= on("submit", event=> { - const value= event.target.elements[name].value; - if(!value) return; - + const el= event.target.elements[name]; event.preventDefault(); - S.action(todosS, "add", value); - event.target.elements[name].value= ""; + S.action(todosS, "add", el.value); + el.value= ""; }); const onremove= on("remove", event=> S.action(todosS, "remove", event.detail)); @@ -62,26 +60,25 @@ export function todosComponent({ todos= [ "Task A" ] }= {}){ ) } /** - * @type {ddeFires<[ "click" ]>} - * @param {{ - * textContent: ddeSignal - * value: number - * }} + * @type {ddeComponent< + * { textContent: ddeSignal, value: number }, + * HTMLLIElement, + * [ "click" ] + * >} * */ -function todoComponent({ textContent, value }){ - const ref= S(); +function todoComponent({ textContent, value }, host){ const onclick= on("click", event=> { const value= Number(event.target.value); event.preventDefault(); event.stopPropagation(); - ref().dispatchEvent(new CustomEvent("remove", { detail: value })); + dispatchEvent(host(), "remove", value); }); const is_editable= S(false); const onedited= on("change", ev=> { textContent(ev.target.value); is_editable(false); }); - return el("li", null, ref).append( + return el("li").append( S.el(is_editable, is=> is ? el("input", { value: textContent(), type: "text" }, onedited) : el("span", textContent, on("click", ()=> is_editable(true))), diff --git a/test/components/webComponent.js b/test/components/webComponent.js new file mode 100644 index 0000000..2e1c9b7 --- /dev/null +++ b/test/components/webComponent.js @@ -0,0 +1,49 @@ +import { el } from "../../index.js"; +import { S } from "../../src/signals.js"; +Object.assign(S, { + customElementParams(_this){ + console.log("zde"); + return getAttributes(_this); + }, + customElementPrototype(cls){ + } +}); + +const store= new WeakMap(); +/** + * Compatible with `npx-wca test/components/webComponent.js` + * @prop {string} test + * */ +class CustomHTMLTestElement extends HTMLElement{ + static get tagName(){ + return "custom-test"; + } + static get observedAttributes(){ + return [ "name" ]; + } + constructor(){ + super(); + customElementInit(this, this.attachShadow({ mode: "open" })); + } + connectedCallback(){ + customElementRender(this, render); + } +} +S.customElementPrototype(CustomHTMLTestElement); +customElements.define(CustomHTMLTestElement.tagName, CustomHTMLTestElement); + +function render({ name }, host){ + return el("p", name); +} +function customElementInit(_this, root= _this){ + const host= (...a)=> a.length ? a[0](_this) : _this; + store.set(_this, { host, root }); +} +function customElementRender(_this, render){ + const { host, root }= store.get(_this); + const attrs= S.customElementParams ? S.customElementParams(_this) : getAttributes(_this); + root.appendChild(render(attrs, host)); +} +function getAttributes(_this){ + return Object.fromEntries(_this.getAttributeNames().map(n=> [ n, _this.getAttribute(n) ])); +} diff --git a/test/exports.js b/test/exports.js index 36a2a99..4186c18 100644 --- a/test/exports.js +++ b/test/exports.js @@ -1,15 +1,16 @@ -import { namespace, el, assign, on, registerReactivity } from "../index.js"; -import { S, isSignal } from "../src/signals.js"; +import * as dde_dom from "../index.js"; +export * from "../index.js"; +import * as dde_s from "../src/signals.js"; +export * from "../src/signals.js"; // import { empty, namespace, on, dispatch } from "../index.js"; // import "../dist/dde-with-signals.js"; // Object.assign(globalThis, dde); // import { el, on, off, S } from "../dist/esm-with-signals.js"; -const style= createStyle(); -Object.assign(globalThis, { S, el, assign, namespace, on, registerReactivity, style }); -export { S, isSignal, el, on, registerReactivity, style }; +export const style= createStyle(); +Object.assign(globalThis, dde_dom, dde_s); function createStyle(){ - const element= el("style"); + const element= dde_dom.el("style"); const store= new WeakSet(); let host; return { diff --git a/test/index.js b/test/index.js index 9b31650..3e01347 100644 --- a/test/index.js +++ b/test/index.js @@ -2,8 +2,11 @@ import { style, el } from './exports.js'; document.head.append(style.element); import { fullNameComponent } from './components/fullNameComponent.js'; import { todosComponent } from './components/todosComponent.js'; +import "./components/webComponent.js"; + document.body.append( el("h1", "Experiments:"), el(fullNameComponent), el(todosComponent), + el("custom-test", { name: "attr" }) );