mirror of
https://github.com/jaandrle/deka-dom-el
synced 2025-07-01 20:32:13 +02:00
🚀 lifecycle events, signals from attrs test
This commit is contained in:
@ -12,17 +12,20 @@ export function on(event, listener, options){
|
||||
}
|
||||
|
||||
const c_ch_o= connectionsChangesObserverConstructor();
|
||||
const els_attribute_store= new WeakSet();
|
||||
import { onAbort } from './helpers.js';
|
||||
//TODO: cleanUp when event before abort?
|
||||
on.connected= function(listener, options){
|
||||
const name= "connected";
|
||||
if(typeof options !== "object")
|
||||
options= {};
|
||||
options.once= true;
|
||||
return function registerElement(element){
|
||||
element.addEventListener("dde:connected", listener, options);
|
||||
if(typeof element.connectedCallback === "function") return element;
|
||||
const event= "dde:"+name;
|
||||
element.addEventListener(event, listener, options);
|
||||
if(typeof element[name+"Callback"] === "function") return element;
|
||||
if(element.isConnected){
|
||||
element.dispatchEvent(new Event("dde:connected"));
|
||||
element.dispatchEvent(new Event(event));
|
||||
return element;
|
||||
}
|
||||
|
||||
@ -32,18 +35,40 @@ on.connected= function(listener, options){
|
||||
};
|
||||
};
|
||||
on.disconnected= function(listener, options){
|
||||
const name= "disconnected";
|
||||
if(typeof options !== "object")
|
||||
options= {};
|
||||
options.once= true;
|
||||
return function registerElement(element){
|
||||
element.addEventListener("dde:disconnected", listener, options);
|
||||
if(typeof element.disconnectedCallback === "function") return element;
|
||||
const event= "dde:"+name;
|
||||
element.addEventListener(event, listener, options);
|
||||
if(typeof element[name+"Callback"] === "function") return element;
|
||||
|
||||
const c= onAbort(options.signal, ()=> c_ch_o.offDisconnected(element, listener));
|
||||
if(c) c_ch_o.onDisconnected(element, listener);
|
||||
return element;
|
||||
};
|
||||
};
|
||||
on.attributeChanged= function(listener, options){
|
||||
const name= "attributeChanged";
|
||||
if(typeof options !== "object")
|
||||
options= {};
|
||||
return function registerElement(element){
|
||||
const event= "dde:"+name;
|
||||
element.addEventListener(event, listener, options);
|
||||
if(typeof element[name+"Callback"] === "function") return element;
|
||||
if(els_attribute_store.has(element)) return element;
|
||||
|
||||
const observer= new MutationObserver(function(mutations){
|
||||
for(const { attributeName, target } of mutations)
|
||||
target.dispatchEvent(
|
||||
new CustomEvent(event, { detail: [ attributeName, target.getAttribute(attributeName) ] }));
|
||||
});
|
||||
const c= onAbort(options.signal, ()=> observer.disconnect());
|
||||
if(c) observer.observe(element, { attributes: true });
|
||||
return element;
|
||||
};
|
||||
};
|
||||
|
||||
function connectionsChangesObserverConstructor(){
|
||||
const store= new Map();
|
||||
|
@ -37,6 +37,22 @@ S.symbols= {
|
||||
signal: mark,
|
||||
onclear: Symbol.for("Signal.onclear")
|
||||
};
|
||||
import { on } from "./events.js";
|
||||
import { scope } from "./dom.js";
|
||||
S.attribute= function(name, initial= undefined){
|
||||
const { host }= scope;
|
||||
const value= host() && host().hasAttribute(name) ? host().getAttribute(name) : initial;
|
||||
const ac= new AbortController();
|
||||
const out= S(value, {
|
||||
[S.symbols.onclear](){ ac.abort(); }
|
||||
});
|
||||
scope.host(on.attributeChanged(function({ detail }){
|
||||
const [ name_c, value ]= detail;
|
||||
if(name_c!==name) return;
|
||||
out(value);
|
||||
}, { signal: ac.signal }));
|
||||
return out;
|
||||
};
|
||||
S.clear= function(...signals){
|
||||
for(const signal of signals){
|
||||
Reflect.deleteProperty(signal, "toJSON");
|
||||
@ -95,7 +111,7 @@ export const signals_config= {
|
||||
|
||||
function create(value, actions){
|
||||
const signal= (...value)=>
|
||||
value.length ? write(signal, value[0]) : read(signal);
|
||||
value.length ? write(signal, ...value) : read(signal);
|
||||
return toSignal(signal, value, actions);
|
||||
}
|
||||
const protoSigal= Object.assign(Object.create(null), {
|
||||
@ -138,10 +154,10 @@ function read(signal){
|
||||
if(deps.has(context)) deps.get(context).add(signal);
|
||||
return value;
|
||||
}
|
||||
function write(signal, value){
|
||||
function write(signal, value, force){
|
||||
if(!signal[mark]) return;
|
||||
const s= signal[mark];
|
||||
if(s.value===value) return;
|
||||
if(!force && s.value===value) return;
|
||||
s.value= value;
|
||||
s.listeners.forEach(l=> l(value));
|
||||
return value;
|
||||
|
Reference in New Issue
Block a user