mirror of
https://github.com/jaandrle/deka-dom-el
synced 2025-07-01 20:32:13 +02:00
🚀 ✨ Remove signal listeners automatically (fixes #20)
This commit is contained in:
17
src/dom.js
17
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;
|
||||
|
@ -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);
|
||||
|
Reference in New Issue
Block a user