mirror of
https://github.com/jaandrle/deka-dom-el
synced 2025-07-01 20:32:13 +02:00
🐛 🚧 connected/disconnected + onAbort
This commit is contained in:
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
};
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
2
src/signals.d.ts
vendored
2
src/signals.d.ts
vendored
@ -44,6 +44,6 @@ interface S {
|
||||
}
|
||||
export const S: S;
|
||||
declare global {
|
||||
type ddeSignal<T, A>= Signal<T, A>;
|
||||
type ddeSignal<T, A= {}>= Signal<T, A>;
|
||||
type ddeActions<V>= Actions<V>
|
||||
}
|
||||
|
Reference in New Issue
Block a user