1
0
mirror of https://github.com/jaandrle/deka-dom-el synced 2024-11-24 17:39:36 +01:00

♻️ Refactore, add abort option

This commit is contained in:
Jan Andrle 2023-08-26 12:20:01 +02:00
parent 7f1506781f
commit a36786042b
Signed by: jaandrle
GPG Key ID: B3A25AED155AFFAB
6 changed files with 54 additions and 25 deletions

View File

@ -1,4 +1,3 @@
import { addSignalListener, isSignal } from './signals.js';
let namespace_curr= "html"; let namespace_curr= "html";
export function namespace(namespace){ export function namespace(namespace){
namespace_curr= namespace==="svg" ? "http://www.w3.org/2000/svg" : namespace; namespace_curr= namespace==="svg" ? "http://www.w3.org/2000/svg" : namespace;
@ -6,8 +5,10 @@ export function namespace(namespace){
append(el){ namespace_curr= "html"; return el; } append(el){ namespace_curr= "html"; return el; }
}; };
} }
import { typeOf } from './helpers.js';
import { isSignal, valueOfSignal } from './signals-common.js';
export function createElement(tag, attributes, ...connect){ export function createElement(tag, attributes, ...connect){
if(typeof attributes==="string" || ( isSignal(attributes) /* TODO && isText*/ )) if(typeOf(attributes)!=="[object Object]" || ( isSignal(attributes) && typeOf(valueOfSignal(attributes))!=="[object Object]" ))
attributes= { textContent: attributes }; attributes= { textContent: attributes };
let el; let el;
switch(true){ switch(true){
@ -22,6 +23,7 @@ export function createElement(tag, attributes, ...connect){
} }
export { createElement as el }; export { createElement as el };
import { addSignalListener } from './signals-common.js';
export function assign(element, ...attributes){ export function assign(element, ...attributes){
if(!attributes.length) return element; if(!attributes.length) return element;
const is_svg= element instanceof SVGElement; const is_svg= element instanceof SVGElement;

View File

@ -1,7 +1,18 @@
import { isSignal, addSignalListener } from './signals.js'; import { isSignal, addSignalListener, removeSignalListener } from './signals-common.js';
export function on(event, listener, options){ export function on(event, listener, options){
if(isSignal(event)) return addSignalListener(event, listener); if(!isSignal(event))
return element=> element.addEventListener(event, listener, options); return element=> element.addEventListener(event, listener, options);
//TODO cleanup when signal removed (also TODO)
if(options && options.signal)
options.signal.addEventListener("abort", ()=> removeSignalListener(event, listener));
return addSignalListener(event, listener);
}
export function off(){//TODO is needed?
const abort= new AbortController();
return new Proxy(()=> abort.abort(), {
get(_, p){ return Reflect.get(abort, p); },
ownKeys(){ return [ "signal" ]; }
})
} }
export function dispatch(event, detail){ export function dispatch(event, detail){
if(typeof event === "string") if(typeof event === "string")
@ -10,6 +21,7 @@ export function dispatch(event, detail){
} }
const connections_changes= connectionsChangesObserverConstructor(); const connections_changes= connectionsChangesObserverConstructor();
//TODO remove listener(s) options
on.connected= function(listener){ on.connected= function(listener){
return function registerElement(element){ return function registerElement(element){
connections_changes.onConnected(element, listener); connections_changes.onConnected(element, listener);

6
src/helpers.js Normal file
View File

@ -0,0 +1,6 @@
export function typeOf(v){
const t= typeof v;
if(t!=="object") return t;
if(v===null) return "null";
return Object.prototype.toString.call(v);
}

23
src/signals-common.js Normal file
View File

@ -0,0 +1,23 @@
export const mark= Symbol.for("signal");
export function isSignal(candidate){
try{ return Reflect.has(candidate, mark); }
catch(e){ return false; }
}
export function valueOfSignal(signal){
return signal[mark].value;
}
export function toSignal(signal, value){
signal[mark]= {
value,
listeners: new Set()
};
return signal;
}
export function addSignalListener(signal, listener){
return signal[mark].listeners.add(listener);
}
export function removeSignalListener(signal, listener){
return signal[mark].listeners.delete(listener);
}

View File

@ -1,11 +1,6 @@
const mark= Symbol.for("signal"); import { mark, isSignal, toSignal, addSignalListener } from "./signals-common.js";
export function isSignal(candidate){ export { isSignal, addSignalListener };
try{ return Reflect.has(candidate, mark); }
catch(e){ return false; }
}
export function addSignalListener(signal, listener){
return signal[mark].listeners.add(listener);
}
export function S(value){ export function S(value){
if(typeof value!=="function") if(typeof value!=="function")
return create(value); return create(value);
@ -59,13 +54,6 @@ function create(value){
value.length ? write(signal, value[0]) : read(signal[mark]); value.length ? write(signal, value[0]) : read(signal[mark]);
return toSignal(signal, value); return toSignal(signal, value);
} }
function toSignal(signal, value){
signal[mark]= {
value,
listeners: new Set()
};
return signal;
}
function createWrapObject(type, signal){ function createWrapObject(type, signal){
return new Proxy(signal, { return new Proxy(signal, {
set(_, p, newValue){ set(_, p, newValue){

View File

@ -1,11 +1,9 @@
import { S, empty, watch, el, namespace, assign, on, dispatch } from "../index.js"; import { S, el, on, off } from "../index.js";
Object.assign(globalThis, { S, watch, el, namespace, assign, on, dispatch }); //import { empty, namespace, on, dispatch } from "../index.js";
Object.assign(globalThis, { S, el, on, off });
const style= createStyle(); const style= createStyle();
const app= el(todosComponent); const app= el(todosComponent);
dispatch("change", "Peter")(app);
console.log(app, app instanceof HTMLDivElement);
document.head.append(style.element); document.head.append(style.element);
document.body.append(app); document.body.append(app);