From 20e95e33d4d7c4b8c22cedeef35663251c21fdea Mon Sep 17 00:00:00 2001 From: Jan Andrle Date: Fri, 8 Sep 2023 20:16:42 +0200 Subject: [PATCH] :sparkles: Move reactive element to the `S.el` MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ⇒ cleanup/simplify signal registration --- src/dom.js | 9 ++------- src/signals-common.js | 4 +--- src/signals-lib.js | 46 ++++++++++++++++++++++--------------------- 3 files changed, 27 insertions(+), 32 deletions(-) diff --git a/src/dom.js b/src/dom.js index 5f042e8..56b4a1a 100644 --- a/src/dom.js +++ b/src/dom.js @@ -12,16 +12,12 @@ export function createElement(tag, attributes, ...connect){ const s= signals(this); let el; //TODO Array.isArray(tag) ⇒ set key (cache els) - if("<>"===tag){ - if(s.isReactiveAtrribute(attributes)) - return s.reactiveElement(attributes, ...connect); - el= document.createDocumentFragment(); - } if(s.isTextContent(attributes)) attributes= { textContent: attributes }; switch(true){ case typeof tag==="function": el= tag(attributes || undefined); 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; case !el: el= assign(document.createElement(tag), attributes); } @@ -40,8 +36,7 @@ export function assign(element, ...attributes){ /* jshint maxcomplexity:15 */ Object.entries(Object.assign({}, ...attributes)).forEach(function assignNth([ key, attr ]){ - if(s.isReactiveAtrribute(attr, key)) - attr= s.processReactiveAttribute(element, key, attr, assignNth); + attr= s.processReactiveAttribute(element, key, attr, assignNth); const [ k ]= key; if("="===k) return setRemoveAttr(key.slice(1), attr); if("."===k) return setDelete(element, key.slice(1), attr); diff --git a/src/signals-common.js b/src/signals-common.js index 961874d..c8029cc 100644 --- a/src/signals-common.js +++ b/src/signals-common.js @@ -1,9 +1,7 @@ import { typeOf } from './helpers.js'; export const signals_global= { - isReactiveAtrribute(attr, key){ return false; }, isTextContent(attributes){ return typeOf(attributes)!=="[object Object]"; }, - processReactiveAttribute(el, key, attr, assignNth){ return false; }, - reactiveElement(attributes, ...connect){ return null; } + processReactiveAttribute(el, key, attr, assignNth){ return attr; }, }; export function registerReactivity(def, global= true){ if(global) return Object.assign(signals_global, def); diff --git a/src/signals-lib.js b/src/signals-lib.js index ef16d15..231ab1a 100644 --- a/src/signals-lib.js +++ b/src/signals-lib.js @@ -39,6 +39,7 @@ S.symbols= { }; S.clear= function(...signals){ for(const signal of signals){ + Reflect.deleteProperty(signal, "toJSON"); const s= signal[mark]; const { onclear }= S.symbols; if(s.actions && s.actions[onclear]) @@ -60,36 +61,36 @@ S.clear= function(...signals){ }); } }; +S.el= function(signal, map){ + const mark_start= document.createComment("<#reactive>"); + const mark_end= document.createComment(""); + const out= document.createDocumentFragment(); + out.append(mark_start, mark_end); + const reRenderReactiveElement= v=> { + if(!mark_start.parentNode || !mark_end.parentNode) + return removeSignalListener(signal, reRenderReactiveElement); + let els= map(v); + if(!Array.isArray(els)) + els= [ els ]; + let el_r= mark_start; + while(( el_r= mark_start.nextSibling ) !== mark_end) + el_r.remove(); + mark_start.after(...els); + }; + addSignalListener(signal, reRenderReactiveElement); + reRenderReactiveElement(signal()); + return out; +}; import { typeOf } from './helpers.js'; export const signals_config= { - isReactiveAtrribute(attr, key){ return isSignal(attr); }, isTextContent(attributes){ return typeOf(attributes)==="string" || ( isSignal(attributes) && typeOf(valueOfSignal(attributes))==="string" ); }, processReactiveAttribute(_, key, attrS, assignNth){ + if(!isSignal(attrS)) return attrS; addSignalListener(attrS, attr=> assignNth([ key, attr ])); return attrS(); - }, - reactiveElement(signal, map){ - const mark_start= document.createComment("<#reactive>"); - const mark_end= document.createComment(""); - const out= document.createDocumentFragment(); - out.append(mark_start, mark_end); - const reRenderReactiveElement= v=> { - if(!mark_start.parentNode || !mark_end.parentNode) - return removeSignalListener(signal, reRenderReactiveElement); - let els= map(v); - if(!Array.isArray(els)) - els= [ els ]; - let el_r= mark_start; - while(( el_r= mark_start.nextSibling ) !== mark_end) - el_r.remove(); - mark_start.after(...els); - }; - addSignalListener(signal, reRenderReactiveElement); - reRenderReactiveElement(signal()); - return out; } }; @@ -108,8 +109,9 @@ function toSignal(signal, value, actions){ actions= {}; signal[mark]= { value, actions, - listeners: new Set(), + listeners: new Set() }; + signal.toJSON= ()=> signal(); Object.setPrototypeOf(signal[mark], protoSigal); return signal; }