From 9f57913f8df57c1c44cd342cbaa1e495ccc2769a Mon Sep 17 00:00:00 2001 From: Jan Andrle Date: Fri, 13 Oct 2023 20:57:21 +0200 Subject: [PATCH] :rocket: :sparkles: Remove signal listeners automatically (fixes #20) --- bs/build.js | 1 + dist/dde-with-signals.js | 282 ++++++++++++++------------ dist/dde.js | 145 ++++++------- dist/esm-with-signals.js | 282 ++++++++++++++------------ dist/esm.js | 145 ++++++------- examples/components/todosComponent.js | 2 +- examples/exports.js | 9 +- package.json | 6 +- src/dom.js | 17 +- src/signals-lib.js | 19 +- 10 files changed, 494 insertions(+), 414 deletions(-) diff --git a/bs/build.js b/bs/build.js index 8650dab..e65c4e4 100755 --- a/bs/build.js +++ b/bs/build.js @@ -10,6 +10,7 @@ for(const file of files){ "--bundle", //"--minify", "--minify-syntax --minify-identifiers", + "--legal-comments=inline", "--packages=external", "--outfile='::out::'" ].join(" "), { file, out }); diff --git a/dist/dde-with-signals.js b/dist/dde-with-signals.js index 8d857e7..2dbfdf3 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 w = { + var y = { isSignal(e) { return !1; }, @@ -9,18 +9,18 @@ return n; } }; - function N(e, t = !0) { - return t ? Object.assign(w, e) : (Object.setPrototypeOf(e, w), e); + function D(e, t = !0) { + return t ? Object.assign(y, e) : (Object.setPrototypeOf(e, y), e); } function x(e) { - return w.isPrototypeOf(e) && e !== w ? e : w; + return y.isPrototypeOf(e) && e !== y ? e : y; } // src/helpers.js - function v(e) { + function E(e) { return typeof e > "u"; } - function j(e) { + function T(e) { let t = typeof e; return t !== "object" ? t : e === null ? "null" : Object.prototype.toString.call(e); } @@ -34,9 +34,9 @@ } // src/dom-common.js - var T = { setDeleteAttr: k }; - function k(e, t, n) { - if (Reflect.set(e, t, n), !!v(n)) { + var M = { setDeleteAttr: G }; + function G(e, t, n) { + if (Reflect.set(e, t, n), !!E(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,17 @@ } // src/dom.js - var y = [{ scope: document.body, namespace: "html", host: (e) => e ? e(document.body) : document.body }], W = (e) => e === "svg" ? "http://www.w3.org/2000/svg" : e, E = { + var S = [{ + scope: document.body, + namespace: "html", + host: (e) => e ? e(document.body) : document.body, + prevent: !0 + }], W = (e) => e === "svg" ? "http://www.w3.org/2000/svg" : e, b = { get current() { - return y[y.length - 1]; + return S[S.length - 1]; }, get state() { - return [...y]; + return [...S]; }, get host() { return this.current.host; @@ -61,26 +66,30 @@ set namespace(e) { return this.current.namespace = W(e); }, + preventDefault() { + let { current: e } = this; + return e.prevent = !0, e; + }, elNamespace(e) { let t = this.namespace; return this.namespace = e, { append(...n) { - return E.namespace = t, n.length === 1 ? n[0] : document.createDocumentFragment().append(...n); + return b.namespace = t, n.length === 1 ? n[0] : document.createDocumentFragment().append(...n); } }; }, push(e = {}) { - return e.namespace && (e.namespace = W(e.namespace)), y.push(Object.assign({}, this.current, e)); + return e.namespace && (e.namespace = W(e.namespace)), S.push(Object.assign({}, this.current, { prevent: !1 }, e)); }, pop() { - return y.pop(); + return S.pop(); } }; function ie(e, t, ...n) { - let r = this, o = x(this), { namespace: c } = E, d = !1, s; + let r = this, o = x(this), { namespace: c } = b, d = !1, s; switch ((Object(t) !== t || o.isSignal(t)) && (t = { textContent: t }), !0) { case typeof e == "function": { - d = !0, E.push({ scope: e, host: (f) => f ? (n.unshift(f), void 0) : s }), s = e(t || void 0); + d = !0, b.push({ scope: e, host: (u) => u ? (n.unshift(u), void 0) : s }), s = e(t || void 0), (s instanceof HTMLElement ? $ : q)(s, "Attribute", "dde-fun", e.name); break; } case e === "#text": @@ -95,44 +104,44 @@ case !s: s = O.call(r, document.createElement(e), t); } - return n.forEach((f) => f(s)), d && E.pop(), s; + return n.forEach((u) => u(s)), d && b.pop(), s; } - var { setDeleteAttr: M } = T; + var { setDeleteAttr: F } = M; function O(e, ...t) { let n = this, r = x(this); if (!t.length) return e; - let c = (e instanceof SVGElement ? J : I).bind(null, e, "Attribute"); - return Object.entries(Object.assign({}, ...t)).forEach(function d([s, f]) { - f = r.processReactiveAttribute(e, s, f, d); - let [m] = s; - if (m === "=") - return c(s.slice(1), f); - if (m === ".") - return F(e, s.slice(1), f); + let c = (e instanceof SVGElement ? q : $).bind(null, e, "Attribute"); + return Object.entries(Object.assign({}, ...t)).forEach(function d([s, u]) { + u = r.processReactiveAttribute(e, s, u, d); + let [p] = s; + if (p === "=") + return c(s.slice(1), u); + if (p === ".") + return z(e, s.slice(1), u); if (/(aria|data)([A-Z])/.test(s)) - return s = s.replace(/([a-z])([A-Z])/g, "$1-$2").toLowerCase(), c(s, f); + return s = s.replace(/([a-z])([A-Z])/g, "$1-$2").toLowerCase(), c(s, u); switch (s === "className" && (s = "class"), s) { case "xlink:href": - return c(s, f, "http://www.w3.org/1999/xlink"); + return c(s, u, "http://www.w3.org/1999/xlink"); case "textContent": - return M(e, s, f); + return F(e, s, u); case "style": - if (typeof f != "object") + if (typeof u != "object") break; case "dataset": - return D(r, f, F.bind(null, e[s])); + return P(r, u, z.bind(null, e[s])); case "ariaset": - return D(r, f, (b, i) => c("aria-" + b, i)); + return P(r, u, (v, i) => c("aria-" + v, i)); case "classList": - return B.call(n, e, f); + return I.call(n, e, u); } - return G(e, s) ? M(e, s, f) : c(s, f); + return J(e, s) ? F(e, s, u) : c(s, u); }), e; } - function B(e, t) { + function I(e, t) { let n = x(this); - return D( + return P( n, t, (r, o) => e.classList.toggle(r, o === -1 ? void 0 : !!o) @@ -141,19 +150,19 @@ function fe(e) { return Array.from(e.children).forEach((t) => t.remove()), e; } - function G(e, t) { + function J(e, t) { if (!Reflect.has(e, t)) return !1; - let n = z(e, t); - return !v(n.set); + let n = H(e, t); + return !E(n.set); } - function z(e, t) { + function H(e, t) { if (e = Object.getPrototypeOf(e), !e) return {}; let n = Object.getOwnPropertyDescriptor(e, t); - return n || z(e, t); + return n || H(e, t); } - function D(e, t, n) { + function P(e, t, n) { if (!(typeof t != "object" || t === null)) return Object.entries(t).forEach(function([o, c]) { o && (c = e.processReactiveAttribute(t, o, c, (d) => n(...d)), n(o, c)); @@ -162,14 +171,14 @@ function U(e) { return Array.isArray(e) ? e.filter(Boolean).join(" ") : e; } - function I(e, t, n, r) { - return e[(v(r) ? "remove" : "set") + t](n, U(r)); + function $(e, t, n, r) { + return e[(E(r) ? "remove" : "set") + t](n, U(r)); } - function J(e, t, n, r, o = null) { - return e[(v(r) ? "remove" : "set") + t + "NS"](o, n, U(r)); + function q(e, t, n, r, o = null) { + return e[(E(r) ? "remove" : "set") + t + "NS"](o, n, U(r)); } - function F(e, t, n) { - if (Reflect.set(e, t, n), !!v(n)) + function z(e, t, n) { + if (Reflect.set(e, t, n), !!E(n)) return Reflect.deleteProperty(e, t); } @@ -178,36 +187,36 @@ let r = n.length ? new CustomEvent(t, { detail: n[0] }) : new Event(t); return e.dispatchEvent(r); } - function S(e, t, n) { + function _(e, t, n) { return function(o) { return o.addEventListener(e, t, n), o; }; } var R = Z(), V = /* @__PURE__ */ new WeakSet(); - S.connected = function(e, t) { + _.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), o.__dde_lifecycleToEvents ? o : o.isConnected ? (o.dispatchEvent(new Event(c)), o) : (A(t.signal, () => R.offConnected(o, e)) && R.onConnected(o, e), o); }; }; - S.disconnected = function(e, t) { + _.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), o.__dde_lifecycleToEvents || A(t.signal, () => R.offDisconnected(o, e)) && R.onDisconnected(o, e), o; }; }; - S.attributeChanged = function(e, t) { + _.attributeChanged = function(e, t) { let n = "attributeChanged"; return typeof t != "object" && (t = {}), function(o) { let c = "dde:" + n; if (o.addEventListener(c, e, t), o.__dde_lifecycleToEvents || V.has(o)) return o; - let d = new MutationObserver(function(f) { - for (let { attributeName: m, target: b } of f) - b.dispatchEvent( - new CustomEvent(c, { detail: [m, b.getAttribute(m)] }) + let d = new MutationObserver(function(u) { + for (let { attributeName: p, target: v } of u) + v.dispatchEvent( + new CustomEvent(c, { detail: [p, v.getAttribute(p)] }) ); }); return A(t.signal, () => d.disconnect()) && d.observe(o, { attributes: !0 }), o; @@ -215,52 +224,52 @@ }; 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)) { + for (let f of i) + if (f.type === "childList") { + if (p(f.addedNodes, !0)) { d(); continue; } - b(u.removedNodes, !0) && d(); + v(f.removedNodes, !0) && d(); } }); return { - onConnected(i, u) { + onConnected(i, f) { c(); let a = o(i); - a.connected.has(u) || (a.connected.add(u), a.length_c += 1); + a.connected.has(f) || (a.connected.add(f), a.length_c += 1); }, - offConnected(i, u) { + offConnected(i, f) { if (!e.has(i)) return; let a = e.get(i); - a.connected.has(u) && (a.connected.delete(u), a.length_c -= 1, r(i, a)); + a.connected.has(f) && (a.connected.delete(f), a.length_c -= 1, r(i, a)); }, - onDisconnected(i, u) { + onDisconnected(i, f) { c(); let a = o(i); - a.disconnected.has(u) || (a.disconnected.add(u), a.length_d += 1); + a.disconnected.has(f) || (a.disconnected.add(f), a.length_d += 1); }, - offDisconnected(i, u) { + offDisconnected(i, f) { if (!e.has(i)) return; let a = e.get(i); - a.disconnected.has(u) && (a.disconnected.delete(u), a.length_d -= 1, r(i, a)); + a.disconnected.has(f) && (a.disconnected.delete(f), a.length_d -= 1, r(i, a)); } }; - function r(i, u) { - u.length_c || u.length_d || (e.delete(i), d()); + function r(i, f) { + f.length_c || f.length_d || (e.delete(i), d()); } function o(i) { if (e.has(i)) return e.get(i); - let u = { + let f = { connected: /* @__PURE__ */ new WeakSet(), length_c: 0, disconnected: /* @__PURE__ */ new WeakSet(), length_d: 0 }; - return e.set(i, u), u; + return e.set(i, f), f; } function c() { t || (t = !0, n.observe(document.body, { childList: !0, subtree: !0 })); @@ -273,29 +282,29 @@ (requestIdleCallback || requestAnimationFrame)(i); }); } - async function f(i) { + async function u(i) { e.size > 30 && await s(); - let u = []; + let f = []; if (!(i instanceof Node)) - return u; + return f; for (let a of e.keys()) - a === i || !(a instanceof Node) || i.contains(a) && u.push(a); - return u; + a === i || !(a instanceof Node) || i.contains(a) && f.push(a); + return f; } - function m(i, u) { + function p(i, f) { let a = !1; - for (let p of i) { - if (u && f(p).then(m), !e.has(p)) + for (let h of i) { + if (f && u(h).then(p), !e.has(h)) continue; - let _ = e.get(p); - _.length_c && (p.dispatchEvent(new Event("dde:connected")), _.connected = /* @__PURE__ */ new WeakSet(), _.length_c = 0, _.length_d || e.delete(p), a = !0); + let w = e.get(h); + w.length_c && (h.dispatchEvent(new Event("dde:connected")), w.connected = /* @__PURE__ */ new WeakSet(), w.length_c = 0, w.length_d || e.delete(h), a = !0); } return a; } - function b(i, u) { + function v(i, f) { let a = !1; - for (let p of i) - u && f(p).then(b), !(!e.has(p) || !e.get(p).length_d) && (p.dispatchEvent(new Event("dde:disconnected")), e.delete(p), a = !0); + for (let h of i) + f && u(h).then(v), !(!e.has(h) || !e.get(h).length_d) && (h.dispatchEvent(new Event("dde:disconnected")), e.delete(h), a = !0); return a; } } @@ -317,16 +326,16 @@ return !1; } } - var g = /* @__PURE__ */ new WeakMap(); - function h(e, t) { + var m = /* @__PURE__ */ new WeakMap(); + function g(e, t) { if (typeof e != "function") - return $(e, t); + return k(e, t); if (C(e)) return e; - let n = $(""), r = () => n(e()); - return g.set(r, /* @__PURE__ */ new Set([n])), X(r), n; + let n = k(""), r = () => n(e()); + return m.set(r, /* @__PURE__ */ new Set([n])), X(r), n; } - h.action = function(e, t, ...n) { + g.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}'!`); @@ -334,66 +343,79 @@ return Reflect.deleteProperty(r, "skip"); r.listeners.forEach((c) => c(r.value)); }; - h.on = function e(t, n, r = {}) { + g.on = function e(t, n, r = {}) { let { signal: o } = r; if (!(o && o.aborted)) { if (Array.isArray(t)) return t.forEach((c) => e(c, n, r)); - P(t, n), o && o.addEventListener("abort", () => H(t, n)); + j(t, n), o && o.addEventListener("abort", () => N(t, n)); } }; - h.symbols = { + g.symbols = { signal: l, onclear: Symbol.for("Signal.onclear") }; - 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]() { + g.attribute = function(e, t = void 0) { + let { host: n } = b, r = n() && n().hasAttribute(e) ? n().getAttribute(e) : t, o = new AbortController(), c = g(r, { + [g.symbols.onclear]() { o.abort(); } }); - return E.host(S.attributeChanged(function({ detail: d }) { - let [s, f] = d; - s === e && c(f); + return b.host(_.attributeChanged(function({ detail: s }) { + let [u, p] = s; + u === e && c(p); }, { signal: o.signal })), c; }; - h.clear = function(...e) { + g.clear = function(...e) { for (let n of e) { Reflect.deleteProperty(n, "toJSON"); - let r = n[l], { onclear: o } = h.symbols; + let r = n[l], { onclear: o } = g.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), !g.has(o)) + if (r.listeners.delete(o), !m.has(o)) return; - let c = g.get(o); - c.delete(n), !(c.size > 1) && (h.clear(...c), g.delete(o)); + let c = m.get(o); + c.delete(n), !(c.size > 1) && (g.clear(...c), m.delete(o)); }); } }; - h.el = function(e, t) { + g.el = function(e, t) { let n = document.createComment("<#reactive>"), r = document.createComment(""), o = document.createDocumentFragment(); o.append(n, r); - let c = (d) => { + let c = (s) => { if (!n.parentNode || !r.parentNode) - return H(e, c); - let s = t(d); - Array.isArray(s) || (s = [s]); - let f = n; - for (; (f = n.nextSibling) !== r; ) - f.remove(); - n.after(...s); + return N(e, c); + let u = t(s); + Array.isArray(u) || (u = [u]); + let p = n; + for (; (p = n.nextSibling) !== r; ) + p.remove(); + n.after(...u); }; - return P(e, c), c(e()), o; + j(e, c); + let { current: d } = b; + return d.prevent || d.host(_.disconnected(() => ( + /*! Clears `S.el` signal listener in current scope when not needed. */ + N(e, c) + ))), c(e()), o; }; - var q = { + var B = { isSignal: C, processReactiveAttribute(e, t, n, r) { - return C(n) ? (P(n, (o) => r([t, o])), n()) : n; + if (!C(n)) + return n; + let o = (d) => r([t, d]); + j(n, o); + let { current: c } = b; + return c.prevent || c.host(_.disconnected(() => ( + /*! Clears signal listener for attribute in `assign` in current scope when not needed. */ + N(n, o) + ))), n(); } }; - function $(e, t) { + function k(e, t) { let n = (...r) => r.length ? te(n, ...r) : ee(n); return Q(n, e, t); } @@ -403,7 +425,7 @@ } }); function Q(e, t, n) { - return j(n) !== "[object Object]" && (n = {}), e[l] = { + return T(n) !== "[object Object]" && (n = {}), e[l] = { value: t, actions: n, listeners: /* @__PURE__ */ new Set() @@ -414,7 +436,7 @@ let t = function() { L.push(t), e(), L.pop(); }; - g.has(e) && (g.set(t, g.get(e)), g.delete(e)), t(); + m.has(e) && (m.set(t, m.get(e)), m.delete(e)), t(); } function Y() { return L[L.length - 1]; @@ -423,7 +445,7 @@ if (!e[l]) return; let { value: t, listeners: n } = e[l], r = Y(); - return r && n.add(r), g.has(r) && g.get(r).add(e), t; + return r && n.add(r), m.has(r) && m.get(r).add(e), t; } function te(e, t, n) { if (!e[l]) @@ -432,30 +454,30 @@ if (!(!n && r.value === t)) return r.value = t, r.listeners.forEach((o) => o(t)), t; } - function P(e, t) { + function j(e, t) { if (e[l]) return e[l].listeners.add(t); } - function H(e, t) { + function N(e, t) { if (e[l]) return e[l].listeners.delete(t); } // signals.js - N(q); + D(B); globalThis.dde= { - S: h, + S: g, assign: O, - classListDeclarative: B, + classListDeclarative: I, createElement: ie, dispatchEvent: le, el: ie, empty: fe, isSignal: C, - on: S, - registerReactivity: N, - scope: E + on: _, + registerReactivity: D, + scope: b }; })(); \ No newline at end of file diff --git a/dist/dde.js b/dist/dde.js index 4fec63f..596886d 100644 --- a/dist/dde.js +++ b/dist/dde.js @@ -9,7 +9,7 @@ return n; } }; - function P(e, t = !0) { + function T(e, t = !0) { return t ? Object.assign(m, e) : (Object.setPrototypeOf(e, m), e); } function b(e) { @@ -30,8 +30,8 @@ } // src/dom-common.js - var C = { setDeleteAttr: j }; - function j(e, t, n) { + var C = { setDeleteAttr: M }; + function M(e, t, 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); @@ -41,7 +41,12 @@ } // src/dom.js - var E = [{ scope: document.body, namespace: "html", host: (e) => e ? e(document.body) : document.body }], R = (e) => e === "svg" ? "http://www.w3.org/2000/svg" : e, x = { + var E = [{ + scope: document.body, + namespace: "html", + host: (e) => e ? e(document.body) : document.body, + prevent: !0 + }], R = (e) => e === "svg" ? "http://www.w3.org/2000/svg" : e, x = { get current() { return E[E.length - 1]; }, @@ -57,6 +62,10 @@ set namespace(e) { return this.current.namespace = R(e); }, + preventDefault() { + let { current: e } = this; + return e.prevent = !0, e; + }, elNamespace(e) { let t = this.namespace; return this.namespace = e, { @@ -66,67 +75,67 @@ }; }, push(e = {}) { - return e.namespace && (e.namespace = R(e.namespace)), E.push(Object.assign({}, this.current, e)); + return e.namespace && (e.namespace = R(e.namespace)), E.push(Object.assign({}, this.current, { prevent: !1 }, e)); }, pop() { return E.pop(); } }; function V(e, t, ...n) { - let i = this, r = b(this), { namespace: f } = x, d = !1, o; + let i = this, r = b(this), { namespace: f } = x, d = !1, c; switch ((Object(t) !== t || r.isSignal(t)) && (t = { textContent: t }), !0) { case typeof e == "function": { - d = !0, x.push({ scope: e, host: (a) => a ? (n.unshift(a), void 0) : o }), o = e(t || void 0); + d = !0, x.push({ scope: e, host: (a) => a ? (n.unshift(a), void 0) : c }), c = e(t || void 0), (c instanceof HTMLElement ? P : j)(c, "Attribute", "dde-fun", e.name); break; } case e === "#text": - o = w.call(i, document.createTextNode(""), t); + c = w.call(i, document.createTextNode(""), t); break; case e === "<>": - o = w.call(i, document.createDocumentFragment(), t); + c = w.call(i, document.createDocumentFragment(), t); break; case f !== "html": - o = w.call(i, document.createElementNS(f, e), t); + c = w.call(i, document.createElementNS(f, e), t); break; - case !o: - o = w.call(i, document.createElement(e), t); + case !c: + c = w.call(i, document.createElement(e), t); } - return n.forEach((a) => a(o)), d && x.pop(), o; + return n.forEach((a) => a(c)), d && x.pop(), c; } var { setDeleteAttr: S } = C; function w(e, ...t) { let n = this, i = b(this); if (!t.length) return e; - let f = (e instanceof SVGElement ? F : W).bind(null, e, "Attribute"); - return Object.entries(Object.assign({}, ...t)).forEach(function d([o, a]) { - a = i.processReactiveAttribute(e, o, a, d); - let [l] = o; + let f = (e instanceof SVGElement ? j : P).bind(null, e, "Attribute"); + return Object.entries(Object.assign({}, ...t)).forEach(function d([c, a]) { + a = i.processReactiveAttribute(e, c, a, d); + let [l] = c; if (l === "=") - return f(o.slice(1), a); + return f(c.slice(1), a); if (l === ".") - return L(e, o.slice(1), a); - if (/(aria|data)([A-Z])/.test(o)) - return o = o.replace(/([a-z])([A-Z])/g, "$1-$2").toLowerCase(), f(o, a); - switch (o === "className" && (o = "class"), o) { + return L(e, c.slice(1), a); + if (/(aria|data)([A-Z])/.test(c)) + return c = c.replace(/([a-z])([A-Z])/g, "$1-$2").toLowerCase(), f(c, a); + switch (c === "className" && (c = "class"), c) { case "xlink:href": - return f(o, a, "http://www.w3.org/1999/xlink"); + return f(c, a, "http://www.w3.org/1999/xlink"); case "textContent": - return S(e, o, a); + return S(e, c, a); case "style": if (typeof a != "object") break; case "dataset": - return O(i, a, L.bind(null, e[o])); + return O(i, a, L.bind(null, e[c])); case "ariaset": - return O(i, a, (h, c) => f("aria-" + h, c)); + return O(i, a, (h, o) => f("aria-" + h, o)); case "classList": - return T.call(n, e, a); + return W.call(n, e, a); } - return M(e, o) ? S(e, o, a) : f(o, a); + return F(e, c) ? S(e, c, a) : f(c, a); }), e; } - function T(e, t) { + function W(e, t) { let n = b(this); return O( n, @@ -137,7 +146,7 @@ function $(e) { return Array.from(e.children).forEach((t) => t.remove()), e; } - function M(e, t) { + function F(e, t) { if (!Reflect.has(e, t)) return !1; let n = D(e, t); @@ -158,10 +167,10 @@ function N(e) { return Array.isArray(e) ? e.filter(Boolean).join(" ") : e; } - function W(e, t, n, i) { + function P(e, t, n, i) { return e[(g(i) ? "remove" : "set") + t](n, N(i)); } - function F(e, t, n, i, r = null) { + function j(e, t, n, i, r = null) { return e[(g(i) ? "remove" : "set") + t + "NS"](r, n, N(i)); } function L(e, t, n) { @@ -179,7 +188,7 @@ return r.addEventListener(e, t, n), r; }; } - var A = q(), U = /* @__PURE__ */ new WeakSet(); + var A = U(), H = /* @__PURE__ */ new WeakSet(); y.connected = function(e, t) { let n = "connected"; return typeof t != "object" && (t = {}), t.once = !0, function(r) { @@ -198,7 +207,7 @@ let n = "attributeChanged"; return typeof t != "object" && (t = {}), function(r) { let f = "dde:" + n; - if (r.addEventListener(f, e, t), r.__dde_lifecycleToEvents || U.has(r)) + if (r.addEventListener(f, e, t), r.__dde_lifecycleToEvents || H.has(r)) return r; let d = new MutationObserver(function(a) { for (let { attributeName: l, target: h } of a) @@ -209,9 +218,9 @@ return _(t.signal, () => d.disconnect()) && d.observe(r, { attributes: !0 }), r; }; }; - function q() { - let e = /* @__PURE__ */ new Map(), t = !1, n = new MutationObserver(function(c) { - for (let s of c) + function U() { + let e = /* @__PURE__ */ new Map(), t = !1, n = new MutationObserver(function(o) { + for (let s of o) if (s.type === "childList") { if (l(s.addedNodes, !0)) { d(); @@ -221,42 +230,42 @@ } }); return { - onConnected(c, s) { + onConnected(o, s) { f(); - let u = r(c); + let u = r(o); u.connected.has(s) || (u.connected.add(s), u.length_c += 1); }, - offConnected(c, s) { - if (!e.has(c)) + offConnected(o, s) { + if (!e.has(o)) return; - let u = e.get(c); - u.connected.has(s) && (u.connected.delete(s), u.length_c -= 1, i(c, u)); + let u = e.get(o); + u.connected.has(s) && (u.connected.delete(s), u.length_c -= 1, i(o, u)); }, - onDisconnected(c, s) { + onDisconnected(o, s) { f(); - let u = r(c); + let u = r(o); u.disconnected.has(s) || (u.disconnected.add(s), u.length_d += 1); }, - offDisconnected(c, s) { - if (!e.has(c)) + offDisconnected(o, s) { + if (!e.has(o)) return; - let u = e.get(c); - u.disconnected.has(s) && (u.disconnected.delete(s), u.length_d -= 1, i(c, u)); + let u = e.get(o); + u.disconnected.has(s) && (u.disconnected.delete(s), u.length_d -= 1, i(o, u)); } }; - function i(c, s) { - s.length_c || s.length_d || (e.delete(c), d()); + function i(o, s) { + s.length_c || s.length_d || (e.delete(o), d()); } - function r(c) { - if (e.has(c)) - return e.get(c); + function r(o) { + if (e.has(o)) + return e.get(o); let s = { connected: /* @__PURE__ */ new WeakSet(), length_c: 0, disconnected: /* @__PURE__ */ new WeakSet(), length_d: 0 }; - return e.set(c, s), s; + return e.set(o, s), s; } function f() { t || (t = !0, n.observe(document.body, { childList: !0, subtree: !0 })); @@ -264,23 +273,23 @@ function d() { !t || e.size || (t = !1, n.disconnect()); } - function o() { - return new Promise(function(c) { - (requestIdleCallback || requestAnimationFrame)(c); + function c() { + return new Promise(function(o) { + (requestIdleCallback || requestAnimationFrame)(o); }); } - async function a(c) { - e.size > 30 && await o(); + async function a(o) { + e.size > 30 && await c(); let s = []; - if (!(c instanceof Node)) + if (!(o instanceof Node)) return s; for (let u of e.keys()) - u === c || !(u instanceof Node) || c.contains(u) && s.push(u); + u === o || !(u instanceof Node) || o.contains(u) && s.push(u); return s; } - function l(c, s) { + function l(o, s) { let u = !1; - for (let p of c) { + for (let p of o) { if (s && a(p).then(l), !e.has(p)) continue; let v = e.get(p); @@ -288,9 +297,9 @@ } return u; } - function h(c, s) { + function h(o, s) { let u = !1; - for (let p of c) + for (let p of o) s && a(p).then(h), !(!e.has(p) || !e.get(p).length_d) && (p.dispatchEvent(new Event("dde:disconnected")), e.delete(p), u = !0); return u; } @@ -306,13 +315,13 @@ globalThis.dde= { assign: w, - classListDeclarative: T, + classListDeclarative: W, createElement: V, dispatchEvent: Q, el: V, empty: $, on: y, - registerReactivity: P, + registerReactivity: T, scope: x }; diff --git a/dist/esm-with-signals.js b/dist/esm-with-signals.js index be556a5..c5f7687 100644 --- a/dist/esm-with-signals.js +++ b/dist/esm-with-signals.js @@ -1,5 +1,5 @@ // src/signals-common.js -var w = { +var y = { isSignal(e) { return !1; }, @@ -7,18 +7,18 @@ var w = { return n; } }; -function N(e, t = !0) { - return t ? Object.assign(w, e) : (Object.setPrototypeOf(e, w), e); +function D(e, t = !0) { + return t ? Object.assign(y, e) : (Object.setPrototypeOf(e, y), e); } function x(e) { - return w.isPrototypeOf(e) && e !== w ? e : w; + return y.isPrototypeOf(e) && e !== y ? e : y; } // src/helpers.js -function v(e) { +function E(e) { return typeof e > "u"; } -function j(e) { +function T(e) { let t = typeof e; return t !== "object" ? t : e === null ? "null" : Object.prototype.toString.call(e); } @@ -32,9 +32,9 @@ function A(e, t) { } // src/dom-common.js -var T = { setDeleteAttr: k }; -function k(e, t, n) { - if (Reflect.set(e, t, n), !!v(n)) { +var M = { setDeleteAttr: G }; +function G(e, t, n) { + if (Reflect.set(e, t, n), !!E(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,17 @@ function k(e, t, n) { } // src/dom.js -var y = [{ scope: document.body, namespace: "html", host: (e) => e ? e(document.body) : document.body }], W = (e) => e === "svg" ? "http://www.w3.org/2000/svg" : e, E = { +var S = [{ + scope: document.body, + namespace: "html", + host: (e) => e ? e(document.body) : document.body, + prevent: !0 +}], W = (e) => e === "svg" ? "http://www.w3.org/2000/svg" : e, b = { get current() { - return y[y.length - 1]; + return S[S.length - 1]; }, get state() { - return [...y]; + return [...S]; }, get host() { return this.current.host; @@ -59,26 +64,30 @@ var y = [{ scope: document.body, namespace: "html", host: (e) => e ? e(document. set namespace(e) { return this.current.namespace = W(e); }, + preventDefault() { + let { current: e } = this; + return e.prevent = !0, e; + }, elNamespace(e) { let t = this.namespace; return this.namespace = e, { append(...n) { - return E.namespace = t, n.length === 1 ? n[0] : document.createDocumentFragment().append(...n); + return b.namespace = t, n.length === 1 ? n[0] : document.createDocumentFragment().append(...n); } }; }, push(e = {}) { - return e.namespace && (e.namespace = W(e.namespace)), y.push(Object.assign({}, this.current, e)); + return e.namespace && (e.namespace = W(e.namespace)), S.push(Object.assign({}, this.current, { prevent: !1 }, e)); }, pop() { - return y.pop(); + return S.pop(); } }; function ie(e, t, ...n) { - let r = this, o = x(this), { namespace: c } = E, d = !1, s; + let r = this, o = x(this), { namespace: c } = b, d = !1, s; switch ((Object(t) !== t || o.isSignal(t)) && (t = { textContent: t }), !0) { case typeof e == "function": { - d = !0, E.push({ scope: e, host: (f) => f ? (n.unshift(f), void 0) : s }), s = e(t || void 0); + d = !0, b.push({ scope: e, host: (u) => u ? (n.unshift(u), void 0) : s }), s = e(t || void 0), (s instanceof HTMLElement ? $ : q)(s, "Attribute", "dde-fun", e.name); break; } case e === "#text": @@ -93,44 +102,44 @@ function ie(e, t, ...n) { case !s: s = O.call(r, document.createElement(e), t); } - return n.forEach((f) => f(s)), d && E.pop(), s; + return n.forEach((u) => u(s)), d && b.pop(), s; } -var { setDeleteAttr: M } = T; +var { setDeleteAttr: F } = M; function O(e, ...t) { let n = this, r = x(this); if (!t.length) return e; - let c = (e instanceof SVGElement ? J : I).bind(null, e, "Attribute"); - return Object.entries(Object.assign({}, ...t)).forEach(function d([s, f]) { - f = r.processReactiveAttribute(e, s, f, d); - let [m] = s; - if (m === "=") - return c(s.slice(1), f); - if (m === ".") - return F(e, s.slice(1), f); + let c = (e instanceof SVGElement ? q : $).bind(null, e, "Attribute"); + return Object.entries(Object.assign({}, ...t)).forEach(function d([s, u]) { + u = r.processReactiveAttribute(e, s, u, d); + let [p] = s; + if (p === "=") + return c(s.slice(1), u); + if (p === ".") + return z(e, s.slice(1), u); if (/(aria|data)([A-Z])/.test(s)) - return s = s.replace(/([a-z])([A-Z])/g, "$1-$2").toLowerCase(), c(s, f); + return s = s.replace(/([a-z])([A-Z])/g, "$1-$2").toLowerCase(), c(s, u); switch (s === "className" && (s = "class"), s) { case "xlink:href": - return c(s, f, "http://www.w3.org/1999/xlink"); + return c(s, u, "http://www.w3.org/1999/xlink"); case "textContent": - return M(e, s, f); + return F(e, s, u); case "style": - if (typeof f != "object") + if (typeof u != "object") break; case "dataset": - return D(r, f, F.bind(null, e[s])); + return P(r, u, z.bind(null, e[s])); case "ariaset": - return D(r, f, (b, i) => c("aria-" + b, i)); + return P(r, u, (v, i) => c("aria-" + v, i)); case "classList": - return B.call(n, e, f); + return I.call(n, e, u); } - return G(e, s) ? M(e, s, f) : c(s, f); + return J(e, s) ? F(e, s, u) : c(s, u); }), e; } -function B(e, t) { +function I(e, t) { let n = x(this); - return D( + return P( n, t, (r, o) => e.classList.toggle(r, o === -1 ? void 0 : !!o) @@ -139,19 +148,19 @@ function B(e, t) { function fe(e) { return Array.from(e.children).forEach((t) => t.remove()), e; } -function G(e, t) { +function J(e, t) { if (!Reflect.has(e, t)) return !1; - let n = z(e, t); - return !v(n.set); + let n = H(e, t); + return !E(n.set); } -function z(e, t) { +function H(e, t) { if (e = Object.getPrototypeOf(e), !e) return {}; let n = Object.getOwnPropertyDescriptor(e, t); - return n || z(e, t); + return n || H(e, t); } -function D(e, t, n) { +function P(e, t, n) { if (!(typeof t != "object" || t === null)) return Object.entries(t).forEach(function([o, c]) { o && (c = e.processReactiveAttribute(t, o, c, (d) => n(...d)), n(o, c)); @@ -160,14 +169,14 @@ function D(e, t, n) { function U(e) { return Array.isArray(e) ? e.filter(Boolean).join(" ") : e; } -function I(e, t, n, r) { - return e[(v(r) ? "remove" : "set") + t](n, U(r)); +function $(e, t, n, r) { + return e[(E(r) ? "remove" : "set") + t](n, U(r)); } -function J(e, t, n, r, o = null) { - return e[(v(r) ? "remove" : "set") + t + "NS"](o, n, U(r)); +function q(e, t, n, r, o = null) { + return e[(E(r) ? "remove" : "set") + t + "NS"](o, n, U(r)); } -function F(e, t, n) { - if (Reflect.set(e, t, n), !!v(n)) +function z(e, t, n) { + if (Reflect.set(e, t, n), !!E(n)) return Reflect.deleteProperty(e, t); } @@ -176,36 +185,36 @@ function le(e, t, ...n) { let r = n.length ? new CustomEvent(t, { detail: n[0] }) : new Event(t); return e.dispatchEvent(r); } -function S(e, t, n) { +function _(e, t, n) { return function(o) { return o.addEventListener(e, t, n), o; }; } var R = Z(), V = /* @__PURE__ */ new WeakSet(); -S.connected = function(e, t) { +_.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), o.__dde_lifecycleToEvents ? o : o.isConnected ? (o.dispatchEvent(new Event(c)), o) : (A(t.signal, () => R.offConnected(o, e)) && R.onConnected(o, e), o); }; }; -S.disconnected = function(e, t) { +_.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), o.__dde_lifecycleToEvents || A(t.signal, () => R.offDisconnected(o, e)) && R.onDisconnected(o, e), o; }; }; -S.attributeChanged = function(e, t) { +_.attributeChanged = function(e, t) { let n = "attributeChanged"; return typeof t != "object" && (t = {}), function(o) { let c = "dde:" + n; if (o.addEventListener(c, e, t), o.__dde_lifecycleToEvents || V.has(o)) return o; - let d = new MutationObserver(function(f) { - for (let { attributeName: m, target: b } of f) - b.dispatchEvent( - new CustomEvent(c, { detail: [m, b.getAttribute(m)] }) + let d = new MutationObserver(function(u) { + for (let { attributeName: p, target: v } of u) + v.dispatchEvent( + new CustomEvent(c, { detail: [p, v.getAttribute(p)] }) ); }); return A(t.signal, () => d.disconnect()) && d.observe(o, { attributes: !0 }), o; @@ -213,52 +222,52 @@ S.attributeChanged = function(e, t) { }; 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)) { + for (let f of i) + if (f.type === "childList") { + if (p(f.addedNodes, !0)) { d(); continue; } - b(u.removedNodes, !0) && d(); + v(f.removedNodes, !0) && d(); } }); return { - onConnected(i, u) { + onConnected(i, f) { c(); let a = o(i); - a.connected.has(u) || (a.connected.add(u), a.length_c += 1); + a.connected.has(f) || (a.connected.add(f), a.length_c += 1); }, - offConnected(i, u) { + offConnected(i, f) { if (!e.has(i)) return; let a = e.get(i); - a.connected.has(u) && (a.connected.delete(u), a.length_c -= 1, r(i, a)); + a.connected.has(f) && (a.connected.delete(f), a.length_c -= 1, r(i, a)); }, - onDisconnected(i, u) { + onDisconnected(i, f) { c(); let a = o(i); - a.disconnected.has(u) || (a.disconnected.add(u), a.length_d += 1); + a.disconnected.has(f) || (a.disconnected.add(f), a.length_d += 1); }, - offDisconnected(i, u) { + offDisconnected(i, f) { if (!e.has(i)) return; let a = e.get(i); - a.disconnected.has(u) && (a.disconnected.delete(u), a.length_d -= 1, r(i, a)); + a.disconnected.has(f) && (a.disconnected.delete(f), a.length_d -= 1, r(i, a)); } }; - function r(i, u) { - u.length_c || u.length_d || (e.delete(i), d()); + function r(i, f) { + f.length_c || f.length_d || (e.delete(i), d()); } function o(i) { if (e.has(i)) return e.get(i); - let u = { + let f = { connected: /* @__PURE__ */ new WeakSet(), length_c: 0, disconnected: /* @__PURE__ */ new WeakSet(), length_d: 0 }; - return e.set(i, u), u; + return e.set(i, f), f; } function c() { t || (t = !0, n.observe(document.body, { childList: !0, subtree: !0 })); @@ -271,29 +280,29 @@ function Z() { (requestIdleCallback || requestAnimationFrame)(i); }); } - async function f(i) { + async function u(i) { e.size > 30 && await s(); - let u = []; + let f = []; if (!(i instanceof Node)) - return u; + return f; for (let a of e.keys()) - a === i || !(a instanceof Node) || i.contains(a) && u.push(a); - return u; + a === i || !(a instanceof Node) || i.contains(a) && f.push(a); + return f; } - function m(i, u) { + function p(i, f) { let a = !1; - for (let p of i) { - if (u && f(p).then(m), !e.has(p)) + for (let h of i) { + if (f && u(h).then(p), !e.has(h)) continue; - let _ = e.get(p); - _.length_c && (p.dispatchEvent(new Event("dde:connected")), _.connected = /* @__PURE__ */ new WeakSet(), _.length_c = 0, _.length_d || e.delete(p), a = !0); + let w = e.get(h); + w.length_c && (h.dispatchEvent(new Event("dde:connected")), w.connected = /* @__PURE__ */ new WeakSet(), w.length_c = 0, w.length_d || e.delete(h), a = !0); } return a; } - function b(i, u) { + function v(i, f) { let a = !1; - for (let p of i) - u && f(p).then(b), !(!e.has(p) || !e.get(p).length_d) && (p.dispatchEvent(new Event("dde:disconnected")), e.delete(p), a = !0); + for (let h of i) + f && u(h).then(v), !(!e.has(h) || !e.get(h).length_d) && (h.dispatchEvent(new Event("dde:disconnected")), e.delete(h), a = !0); return a; } } @@ -315,16 +324,16 @@ function C(e) { return !1; } } -var g = /* @__PURE__ */ new WeakMap(); -function h(e, t) { +var m = /* @__PURE__ */ new WeakMap(); +function g(e, t) { if (typeof e != "function") - return $(e, t); + return k(e, t); if (C(e)) return e; - let n = $(""), r = () => n(e()); - return g.set(r, /* @__PURE__ */ new Set([n])), X(r), n; + let n = k(""), r = () => n(e()); + return m.set(r, /* @__PURE__ */ new Set([n])), X(r), n; } -h.action = function(e, t, ...n) { +g.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}'!`); @@ -332,66 +341,79 @@ h.action = function(e, t, ...n) { return Reflect.deleteProperty(r, "skip"); r.listeners.forEach((c) => c(r.value)); }; -h.on = function e(t, n, r = {}) { +g.on = function e(t, n, r = {}) { let { signal: o } = r; if (!(o && o.aborted)) { if (Array.isArray(t)) return t.forEach((c) => e(c, n, r)); - P(t, n), o && o.addEventListener("abort", () => H(t, n)); + j(t, n), o && o.addEventListener("abort", () => N(t, n)); } }; -h.symbols = { +g.symbols = { signal: l, onclear: Symbol.for("Signal.onclear") }; -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]() { +g.attribute = function(e, t = void 0) { + let { host: n } = b, r = n() && n().hasAttribute(e) ? n().getAttribute(e) : t, o = new AbortController(), c = g(r, { + [g.symbols.onclear]() { o.abort(); } }); - return E.host(S.attributeChanged(function({ detail: d }) { - let [s, f] = d; - s === e && c(f); + return b.host(_.attributeChanged(function({ detail: s }) { + let [u, p] = s; + u === e && c(p); }, { signal: o.signal })), c; }; -h.clear = function(...e) { +g.clear = function(...e) { for (let n of e) { Reflect.deleteProperty(n, "toJSON"); - let r = n[l], { onclear: o } = h.symbols; + let r = n[l], { onclear: o } = g.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), !g.has(o)) + if (r.listeners.delete(o), !m.has(o)) return; - let c = g.get(o); - c.delete(n), !(c.size > 1) && (h.clear(...c), g.delete(o)); + let c = m.get(o); + c.delete(n), !(c.size > 1) && (g.clear(...c), m.delete(o)); }); } }; -h.el = function(e, t) { +g.el = function(e, t) { let n = document.createComment("<#reactive>"), r = document.createComment(""), o = document.createDocumentFragment(); o.append(n, r); - let c = (d) => { + let c = (s) => { if (!n.parentNode || !r.parentNode) - return H(e, c); - let s = t(d); - Array.isArray(s) || (s = [s]); - let f = n; - for (; (f = n.nextSibling) !== r; ) - f.remove(); - n.after(...s); + return N(e, c); + let u = t(s); + Array.isArray(u) || (u = [u]); + let p = n; + for (; (p = n.nextSibling) !== r; ) + p.remove(); + n.after(...u); }; - return P(e, c), c(e()), o; + j(e, c); + let { current: d } = b; + return d.prevent || d.host(_.disconnected(() => ( + /*! Clears `S.el` signal listener in current scope when not needed. */ + N(e, c) + ))), c(e()), o; }; -var q = { +var B = { isSignal: C, processReactiveAttribute(e, t, n, r) { - return C(n) ? (P(n, (o) => r([t, o])), n()) : n; + if (!C(n)) + return n; + let o = (d) => r([t, d]); + j(n, o); + let { current: c } = b; + return c.prevent || c.host(_.disconnected(() => ( + /*! Clears signal listener for attribute in `assign` in current scope when not needed. */ + N(n, o) + ))), n(); } }; -function $(e, t) { +function k(e, t) { let n = (...r) => r.length ? te(n, ...r) : ee(n); return Q(n, e, t); } @@ -401,7 +423,7 @@ var K = Object.assign(/* @__PURE__ */ Object.create(null), { } }); function Q(e, t, n) { - return j(n) !== "[object Object]" && (n = {}), e[l] = { + return T(n) !== "[object Object]" && (n = {}), e[l] = { value: t, actions: n, listeners: /* @__PURE__ */ new Set() @@ -412,7 +434,7 @@ function X(e) { let t = function() { L.push(t), e(), L.pop(); }; - g.has(e) && (g.set(t, g.get(e)), g.delete(e)), t(); + m.has(e) && (m.set(t, m.get(e)), m.delete(e)), t(); } function Y() { return L[L.length - 1]; @@ -421,7 +443,7 @@ function ee(e) { if (!e[l]) return; let { value: t, listeners: n } = e[l], r = Y(); - return r && n.add(r), g.has(r) && g.get(r).add(e), t; + return r && n.add(r), m.has(r) && m.get(r).add(e), t; } function te(e, t, n) { if (!e[l]) @@ -430,27 +452,27 @@ function te(e, t, n) { if (!(!n && r.value === t)) return r.value = t, r.listeners.forEach((o) => o(t)), t; } -function P(e, t) { +function j(e, t) { if (e[l]) return e[l].listeners.add(t); } -function H(e, t) { +function N(e, t) { if (e[l]) return e[l].listeners.delete(t); } // signals.js -N(q); +D(B); export { - h as S, + g as S, O as assign, - B as classListDeclarative, + I as classListDeclarative, ie as createElement, le as dispatchEvent, ie as el, fe as empty, C as isSignal, - S as on, - N as registerReactivity, - E as scope + _ as on, + D as registerReactivity, + b as scope }; diff --git a/dist/esm.js b/dist/esm.js index 29b76ea..e5d09fd 100644 --- a/dist/esm.js +++ b/dist/esm.js @@ -7,7 +7,7 @@ var m = { return n; } }; -function P(e, t = !0) { +function T(e, t = !0) { return t ? Object.assign(m, e) : (Object.setPrototypeOf(e, m), e); } function b(e) { @@ -28,8 +28,8 @@ function _(e, t) { } // src/dom-common.js -var C = { setDeleteAttr: j }; -function j(e, t, n) { +var C = { setDeleteAttr: M }; +function M(e, t, 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); @@ -39,7 +39,12 @@ function j(e, t, n) { } // src/dom.js -var E = [{ scope: document.body, namespace: "html", host: (e) => e ? e(document.body) : document.body }], R = (e) => e === "svg" ? "http://www.w3.org/2000/svg" : e, x = { +var E = [{ + scope: document.body, + namespace: "html", + host: (e) => e ? e(document.body) : document.body, + prevent: !0 +}], R = (e) => e === "svg" ? "http://www.w3.org/2000/svg" : e, x = { get current() { return E[E.length - 1]; }, @@ -55,6 +60,10 @@ var E = [{ scope: document.body, namespace: "html", host: (e) => e ? e(document. set namespace(e) { return this.current.namespace = R(e); }, + preventDefault() { + let { current: e } = this; + return e.prevent = !0, e; + }, elNamespace(e) { let t = this.namespace; return this.namespace = e, { @@ -64,67 +73,67 @@ var E = [{ scope: document.body, namespace: "html", host: (e) => e ? e(document. }; }, push(e = {}) { - return e.namespace && (e.namespace = R(e.namespace)), E.push(Object.assign({}, this.current, e)); + return e.namespace && (e.namespace = R(e.namespace)), E.push(Object.assign({}, this.current, { prevent: !1 }, e)); }, pop() { return E.pop(); } }; function V(e, t, ...n) { - let i = this, r = b(this), { namespace: f } = x, d = !1, o; + let i = this, r = b(this), { namespace: f } = x, d = !1, c; switch ((Object(t) !== t || r.isSignal(t)) && (t = { textContent: t }), !0) { case typeof e == "function": { - d = !0, x.push({ scope: e, host: (a) => a ? (n.unshift(a), void 0) : o }), o = e(t || void 0); + d = !0, x.push({ scope: e, host: (a) => a ? (n.unshift(a), void 0) : c }), c = e(t || void 0), (c instanceof HTMLElement ? P : j)(c, "Attribute", "dde-fun", e.name); break; } case e === "#text": - o = w.call(i, document.createTextNode(""), t); + c = w.call(i, document.createTextNode(""), t); break; case e === "<>": - o = w.call(i, document.createDocumentFragment(), t); + c = w.call(i, document.createDocumentFragment(), t); break; case f !== "html": - o = w.call(i, document.createElementNS(f, e), t); + c = w.call(i, document.createElementNS(f, e), t); break; - case !o: - o = w.call(i, document.createElement(e), t); + case !c: + c = w.call(i, document.createElement(e), t); } - return n.forEach((a) => a(o)), d && x.pop(), o; + return n.forEach((a) => a(c)), d && x.pop(), c; } var { setDeleteAttr: S } = C; function w(e, ...t) { let n = this, i = b(this); if (!t.length) return e; - let f = (e instanceof SVGElement ? F : W).bind(null, e, "Attribute"); - return Object.entries(Object.assign({}, ...t)).forEach(function d([o, a]) { - a = i.processReactiveAttribute(e, o, a, d); - let [l] = o; + let f = (e instanceof SVGElement ? j : P).bind(null, e, "Attribute"); + return Object.entries(Object.assign({}, ...t)).forEach(function d([c, a]) { + a = i.processReactiveAttribute(e, c, a, d); + let [l] = c; if (l === "=") - return f(o.slice(1), a); + return f(c.slice(1), a); if (l === ".") - return L(e, o.slice(1), a); - if (/(aria|data)([A-Z])/.test(o)) - return o = o.replace(/([a-z])([A-Z])/g, "$1-$2").toLowerCase(), f(o, a); - switch (o === "className" && (o = "class"), o) { + return L(e, c.slice(1), a); + if (/(aria|data)([A-Z])/.test(c)) + return c = c.replace(/([a-z])([A-Z])/g, "$1-$2").toLowerCase(), f(c, a); + switch (c === "className" && (c = "class"), c) { case "xlink:href": - return f(o, a, "http://www.w3.org/1999/xlink"); + return f(c, a, "http://www.w3.org/1999/xlink"); case "textContent": - return S(e, o, a); + return S(e, c, a); case "style": if (typeof a != "object") break; case "dataset": - return O(i, a, L.bind(null, e[o])); + return O(i, a, L.bind(null, e[c])); case "ariaset": - return O(i, a, (h, c) => f("aria-" + h, c)); + return O(i, a, (h, o) => f("aria-" + h, o)); case "classList": - return T.call(n, e, a); + return W.call(n, e, a); } - return M(e, o) ? S(e, o, a) : f(o, a); + return F(e, c) ? S(e, c, a) : f(c, a); }), e; } -function T(e, t) { +function W(e, t) { let n = b(this); return O( n, @@ -135,7 +144,7 @@ function T(e, t) { function $(e) { return Array.from(e.children).forEach((t) => t.remove()), e; } -function M(e, t) { +function F(e, t) { if (!Reflect.has(e, t)) return !1; let n = D(e, t); @@ -156,10 +165,10 @@ function O(e, t, n) { function N(e) { return Array.isArray(e) ? e.filter(Boolean).join(" ") : e; } -function W(e, t, n, i) { +function P(e, t, n, i) { return e[(g(i) ? "remove" : "set") + t](n, N(i)); } -function F(e, t, n, i, r = null) { +function j(e, t, n, i, r = null) { return e[(g(i) ? "remove" : "set") + t + "NS"](r, n, N(i)); } function L(e, t, n) { @@ -177,7 +186,7 @@ function y(e, t, n) { return r.addEventListener(e, t, n), r; }; } -var A = q(), U = /* @__PURE__ */ new WeakSet(); +var A = U(), H = /* @__PURE__ */ new WeakSet(); y.connected = function(e, t) { let n = "connected"; return typeof t != "object" && (t = {}), t.once = !0, function(r) { @@ -196,7 +205,7 @@ y.attributeChanged = function(e, t) { let n = "attributeChanged"; return typeof t != "object" && (t = {}), function(r) { let f = "dde:" + n; - if (r.addEventListener(f, e, t), r.__dde_lifecycleToEvents || U.has(r)) + if (r.addEventListener(f, e, t), r.__dde_lifecycleToEvents || H.has(r)) return r; let d = new MutationObserver(function(a) { for (let { attributeName: l, target: h } of a) @@ -207,9 +216,9 @@ y.attributeChanged = function(e, t) { return _(t.signal, () => d.disconnect()) && d.observe(r, { attributes: !0 }), r; }; }; -function q() { - let e = /* @__PURE__ */ new Map(), t = !1, n = new MutationObserver(function(c) { - for (let s of c) +function U() { + let e = /* @__PURE__ */ new Map(), t = !1, n = new MutationObserver(function(o) { + for (let s of o) if (s.type === "childList") { if (l(s.addedNodes, !0)) { d(); @@ -219,42 +228,42 @@ function q() { } }); return { - onConnected(c, s) { + onConnected(o, s) { f(); - let u = r(c); + let u = r(o); u.connected.has(s) || (u.connected.add(s), u.length_c += 1); }, - offConnected(c, s) { - if (!e.has(c)) + offConnected(o, s) { + if (!e.has(o)) return; - let u = e.get(c); - u.connected.has(s) && (u.connected.delete(s), u.length_c -= 1, i(c, u)); + let u = e.get(o); + u.connected.has(s) && (u.connected.delete(s), u.length_c -= 1, i(o, u)); }, - onDisconnected(c, s) { + onDisconnected(o, s) { f(); - let u = r(c); + let u = r(o); u.disconnected.has(s) || (u.disconnected.add(s), u.length_d += 1); }, - offDisconnected(c, s) { - if (!e.has(c)) + offDisconnected(o, s) { + if (!e.has(o)) return; - let u = e.get(c); - u.disconnected.has(s) && (u.disconnected.delete(s), u.length_d -= 1, i(c, u)); + let u = e.get(o); + u.disconnected.has(s) && (u.disconnected.delete(s), u.length_d -= 1, i(o, u)); } }; - function i(c, s) { - s.length_c || s.length_d || (e.delete(c), d()); + function i(o, s) { + s.length_c || s.length_d || (e.delete(o), d()); } - function r(c) { - if (e.has(c)) - return e.get(c); + function r(o) { + if (e.has(o)) + return e.get(o); let s = { connected: /* @__PURE__ */ new WeakSet(), length_c: 0, disconnected: /* @__PURE__ */ new WeakSet(), length_d: 0 }; - return e.set(c, s), s; + return e.set(o, s), s; } function f() { t || (t = !0, n.observe(document.body, { childList: !0, subtree: !0 })); @@ -262,23 +271,23 @@ function q() { function d() { !t || e.size || (t = !1, n.disconnect()); } - function o() { - return new Promise(function(c) { - (requestIdleCallback || requestAnimationFrame)(c); + function c() { + return new Promise(function(o) { + (requestIdleCallback || requestAnimationFrame)(o); }); } - async function a(c) { - e.size > 30 && await o(); + async function a(o) { + e.size > 30 && await c(); let s = []; - if (!(c instanceof Node)) + if (!(o instanceof Node)) return s; for (let u of e.keys()) - u === c || !(u instanceof Node) || c.contains(u) && s.push(u); + u === o || !(u instanceof Node) || o.contains(u) && s.push(u); return s; } - function l(c, s) { + function l(o, s) { let u = !1; - for (let p of c) { + for (let p of o) { if (s && a(p).then(l), !e.has(p)) continue; let v = e.get(p); @@ -286,9 +295,9 @@ function q() { } return u; } - function h(c, s) { + function h(o, s) { let u = !1; - for (let p of c) + for (let p of o) s && a(p).then(h), !(!e.has(p) || !e.get(p).length_d) && (p.dispatchEvent(new Event("dde:disconnected")), e.delete(p), u = !0); return u; } @@ -303,12 +312,12 @@ function q() { }); export { w as assign, - T as classListDeclarative, + W as classListDeclarative, V as createElement, Q as dispatchEvent, V as el, $ as empty, y as on, - P as registerReactivity, + T as registerReactivity, x as scope }; diff --git a/examples/components/todosComponent.js b/examples/components/todosComponent.js index 0df75ac..4fd7cd9 100644 --- a/examples/components/todosComponent.js +++ b/examples/components/todosComponent.js @@ -18,7 +18,7 @@ const className= style.host(todosComponent).css` export function todosComponent({ todos= [ "Task A" ] }= {}){ const todosS= S(todos.map(t=> S(t)), { add(v){ this.value.push(S(v)); }, - remove(i){ S.clear(this.value.splice(i, 1)[0]); }, + remove(i){ this.value.splice(i, 1)[0]; }, [S.symbols.onclear](){ S.clear(...this.value); }, }); const name= "todoName"; diff --git a/examples/exports.js b/examples/exports.js index f356813..8c4928f 100644 --- a/examples/exports.js +++ b/examples/exports.js @@ -2,12 +2,11 @@ import * as dde_dom from "../index.js"; export * from "../index.js"; import * as dde_s from "../signals.js"; export * from "../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"; -export const style= createStyle(); Object.assign(globalThis, dde_dom, dde_s); +//import * as dde_dom from "../dist/esm-with-signals.js"; +//export * from "../dist/esm-with-signals.js"; +//Object.assign(globalThis, dde_dom); +export const style= createStyle(); function createStyle(){ const element= dde_dom.el("style"); diff --git a/package.json b/package.json index 800cdd6..84f8bf7 100644 --- a/package.json +++ b/package.json @@ -48,7 +48,7 @@ "latedef": "true", "maxparams": 5, "maxdepth": 3, - "maxcomplexity": 10, + "maxcomplexity": 11, "globals": { "requestIdleCallback": false, "AbortController": false, @@ -58,12 +58,12 @@ "size-limit": [ { "path": "./index.js", - "limit": "7 kB", + "limit": "8 kB", "gzip": false }, { "path": "./signals.js", - "limit": "7 kB", + "limit": "8 kB", "gzip": false }, { diff --git a/src/dom.js b/src/dom.js index 28834db..0f4b18f 100644 --- a/src/dom.js +++ b/src/dom.js @@ -1,7 +1,12 @@ import { signals } from "./signals-common.js"; -/** @type {{ namespace: "html"|string, host: function }[]} */ -const scopes= [ { scope: document.body, namespace: "html", host: c=> c ? c(document.body) : document.body } ]; +/** @type {{ scope: object, prevent: boolean, namespace: "html"|string, host: function }[]} */ +const scopes= [ { + scope: document.body, + namespace: "html", + host: c=> c ? c(document.body) : document.body, + prevent: true +} ]; const namespaceHelper= ns=> ns==="svg" ? "http://www.w3.org/2000/svg" : ns; export const scope= { get current(){ return scopes[scopes.length-1]; }, @@ -9,6 +14,11 @@ export const scope= { get host(){ return this.current.host; }, get namespace(){ return this.current.namespace; }, set namespace(namespace){ return ( this.current.namespace= namespaceHelper(namespace)); }, + preventDefault(){ + const { current }= this; + current.prevent= true; + return current; + }, elNamespace(namespace){ const ns= this.namespace; this.namespace= namespace; @@ -23,7 +33,7 @@ export const scope= { }, push(s= {}){ if(s.namespace) s.namespace= namespaceHelper(s.namespace); - return scopes.push(Object.assign({}, this.current, s)); + return scopes.push(Object.assign({}, this.current, { prevent: false }, s)); }, pop(){ return scopes.pop(); }, }; @@ -41,6 +51,7 @@ export function createElement(tag, attributes, ...connect){ scoped= true; scope.push({ scope: tag, host: c=> c ? (connect.unshift(c), undefined) : el }); el= tag(attributes || undefined); + (el instanceof HTMLElement ? setRemove : setRemoveNS)(el, "Attribute", "dde-fun", tag.name); break; } case tag==="#text": el= assign.call(_this, document.createTextNode(""), attributes); break; diff --git a/src/signals-lib.js b/src/signals-lib.js index 4b1e120..51d7a87 100644 --- a/src/signals-lib.js +++ b/src/signals-lib.js @@ -46,7 +46,7 @@ S.attribute= function(name, initial= undefined){ const out= S(value, { [S.symbols.onclear](){ ac.abort(); } }); - scope.host(on.attributeChanged(function({ detail }){ + scope.host(on.attributeChanged(function attributeChangeToSignal({ detail }){ const [ name_c, value ]= detail; if(name_c!==name) return; out(value); @@ -94,6 +94,11 @@ S.el= function(signal, map){ mark_start.after(...els); }; addSignalListener(signal, reRenderReactiveElement); + const { current }= scope; + if(!current.prevent) + current.host(on.disconnected(()=> + /*! Clears `S.el` signal listener in current scope when not needed. */ + removeSignalListener(signal, reRenderReactiveElement))); reRenderReactiveElement(signal()); return out; }; @@ -102,9 +107,14 @@ import { typeOf } from './helpers.js'; export const signals_config= { isSignal, processReactiveAttribute(_, key, attrs, assignNth){ - //TODO DOC: once the signal is used as attribute, there is no reason to use assign again (if for some reason needed, use imperative listeners clear with `S.clear`) if(!isSignal(attrs)) return attrs; - addSignalListener(attrs, attr=> assignNth([ key, attr ])); + const l= attr=> assignNth([ key, attr ]); + addSignalListener(attrs, l); + const { current }= scope; + if(!current.prevent) + current.host(on.disconnected(()=> + /*! Clears signal listener for attribute in `assign` in current scope when not needed. */ + removeSignalListener(attrs, l))); return attrs(); } }; @@ -163,9 +173,6 @@ function write(signal, value, force){ return value; } -function valueOfSignal(signal){ - return signal[mark].value; -} function addSignalListener(signal, listener){ if(!signal[mark]) return; return signal[mark].listeners.add(listener);