diff --git a/bs/docs.js b/bs/docs.js index 4c89dd1..f87bb61 100755 --- a/bs/docs.js +++ b/bs/docs.js @@ -2,48 +2,25 @@ /* jshint esversion: 11,-W097, -W040, module: true, node: true, expr: true, undef: true *//* global echo, $, pipe, s, fetch, cyclicLoop */ echo("Building static documentation files…"); echo("Preparing…"); -const path_target= { - root: "docs/", - css: "docs/" -}; +import { path_target, pages, styles, dispatchEvent } from "../docs_src/ssr.js"; import { createHTMl } from "./docs/jsdom.js"; import { register } from "../jsdom.js"; const pkg= s.cat("package.json").xargs(JSON.parse); -const pages= [ - { id: "index", title: "Introduction", description: "Introducing a library and motivations." }, - { id: "elements", title: "Elements", description: "Basic concepts of elements modifications and creations." } -]; for(const info of pages){ const { id }= info; echo(`Generating ${id}.html…`); const ssr= createHTMl(""); const { el }= await register(ssr.dom); - const { page, css }= await import(`../docs_src/${id}.html.js`); //→ TODO: important to mention in docs!!! + const { page }= await import(`../docs_src/${id}.html.js`); //→ TODO: important to mention in docs!!! document.body.append( - el(page, { pkg, info, path_target, pages, registerClientFile }), + el(page, { pkg, info }), ); echo.use("-R", `Writing ${id}.html…`); + dispatchEvent("oneachrender", document); s.echo(ssr.serialize()).to(path_target.root+id+".html"); - s.echo(css.content).to(path_target.css+id+".css"); } +s.echo(styles.content).to(path_target.css+styles.name); +dispatchEvent("onssrend"); echo("Done"); - - -/** - * @typedef registerClientFile - * @type {function} - * @param {URL} url - * @param {HTMLScriptElement|HTMLLinkElement} [element_head] - * */ -function registerClientFile(url, element_head){ - const file_name= url.pathname.split("/").pop(); - s.cat(url).to(path_target.root+file_name); - - if(!element_head) return; - element_head[element_head instanceof HTMLScriptElement ? "src" : "href"]= file_name; - document.head.append( - element_head - ); -} diff --git a/dist/dde-with-signals.js b/dist/dde-with-signals.js index ad8d415..91bdea4 100644 --- a/dist/dde-with-signals.js +++ b/dist/dde-with-signals.js @@ -1,23 +1,23 @@ //deka-dom-el library is available via global namespace `dde` (()=> { -var y={isSignal(t){return!1},processReactiveAttribute(t,e,n,o){return n}};function M(t,e=!0){return e?Object.assign(y,t):(Object.setPrototypeOf(t,y),t)}function R(t){return y.isPrototypeOf(t)&&t!==y?t:y}function v(t){return typeof t>"u"}function F(t){let e=typeof t;return e!=="object"?e:t===null?"null":Object.prototype.toString.call(t)}function C(t,e){if(!t||!(t instanceof AbortSignal))return!0;if(!t.aborted)return t.addEventListener("abort",e),function(){t.removeEventListener("abort",e)}}var U={setDeleteAttr:X};function X(t,e,n){if(Reflect.set(t,e,n),!!v(n)){if(Reflect.deleteProperty(t,e),t instanceof HTMLElement&&t.getAttribute(e)==="undefined")return t.removeAttribute(e);if(Reflect.get(t,e)==="undefined")return Reflect.set(t,e,"")}}var w=[{scope:document.body,host:t=>t?t(document.body):document.body,prevent:!0,inherit_host:!1}],_={get current(){return w[w.length-1]},get host(){return this.current.host},preventDefault(){let{current:t}=this;return t.prevent=!0,t},get state(){return[...w]},push(t={}){return w.push(Object.assign({},this.current,{prevent:!1},t))},pop(){return w.pop()}},L;function m(t,e,...n){let o=R(this),r=0,c,s;switch((Object(e)!==e||o.isSignal(e))&&(e={textContent:e}),!0){case typeof t=="function":{r=1;let{inherit_host:a,host:d}=_.current,h=a?d:i=>i?(r===1?n.unshift(i):i(s),void 0):s;_.push({scope:t,host:h,inherit_host:a}),c=t(e||void 0);let E=c instanceof DocumentFragment,u=m.mark({type:"component",name:t.name,host:E?"this":c.nodeName==="#comment"?"previousLater":"parentElement"});c.prepend(u),E&&(s=u);break}case t==="#text":c=N.call(this,document.createTextNode(""),e);break;case(t==="<>"||!t):c=N.call(this,document.createDocumentFragment(),e);break;case L:c=N.call(this,document.createElementNS(L,t),e);break;case!c:c=N.call(this,document.createElement(t),e)}return rt(c),s||(s=c),n.forEach(a=>a(s)),r&&_.pop(),r=2,c}m.mark=function(t,e=!1){t=Object.entries(t).map(([r,c])=>r+`="${c}"`).join(" ");let n=e?"":"/",o=document.createComment(``);return e||(o.end=document.createComment("")),o};m.later=function(){let t=m.mark({type:"later"});return t.append=t.prepend=function(...e){return t.after(...e),t},t};function bt(t){let e=this;return function(...o){L=t;let r=m.call(e,...o);return L=void 0,r}}var{setDeleteAttr:q}=U,P=new WeakMap;function N(t,...e){if(!e.length)return t;P.set(t,J(t,this));for(let[n,o]of Object.entries(Object.assign({},...e)))I.call(this,t,n,o);return P.delete(t),t}function I(t,e,n){let{setRemoveAttr:o,s:r}=J(t,this),c=this;n=r.processReactiveAttribute(t,e,n,(a,d)=>I.call(c,t,a,d));let[s]=e;if(s==="=")return o(e.slice(1),n);if(s===".")return H(t,e.slice(1),n);if(/(aria|data)([A-Z])/.test(e))return e=e.replace(/([a-z])([A-Z])/g,"$1-$2").toLowerCase(),o(e,n);switch(e==="className"&&(e="class"),e){case"xlink:href":return o(e,n,"http://www.w3.org/1999/xlink");case"textContent":return q(t,e,n);case"style":if(typeof n!="object")break;case"dataset":return W(r,n,H.bind(null,t[e]));case"ariaset":return W(r,n,(a,d)=>o("aria-"+a,d));case"classList":return Y.call(c,t,n)}return tt(t,e)?q(t,e,n):o(e,n)}function J(t,e){if(P.has(t))return P.get(t);let o=(t instanceof SVGElement?nt:et).bind(null,t,"Attribute"),r=R(e);return{setRemoveAttr:o,s:r}}function Y(t,e){let n=R(this);return W(n,e,(o,r)=>t.classList.toggle(o,r===-1?void 0:!!r)),t}function Et(t){return Array.from(t.children).forEach(e=>e.remove()),t}function tt(t,e){if(!Reflect.has(t,e))return!1;let n=Z(t,e);return!v(n.set)}function Z(t,e){if(t=Object.getPrototypeOf(t),!t)return{};let n=Object.getOwnPropertyDescriptor(t,e);return n||Z(t,e)}function W(t,e,n){if(!(typeof e!="object"||e===null))return Object.entries(e).forEach(function([r,c]){r&&(c=t.processReactiveAttribute(e,r,c,n),n(r,c))})}function G(t){return Array.isArray(t)?t.filter(Boolean).join(" "):t}function et(t,e,n,o){return t[(v(o)?"remove":"set")+e](n,G(o))}function nt(t,e,n,o,r=null){return t[(v(o)?"remove":"set")+e+"NS"](r,n,G(o))}function H(t,e,n){if(Reflect.set(t,e,n),!!v(n))return Reflect.deleteProperty(t,e)}function B(...t){return this.appendOrig(...t),this}function rt(t){return t.append===B||(t.appendOrig=t.append,t.append=B),t}function xt(t,e,...n){let o=n.length?new CustomEvent(e,{detail:n[0]}):new Event(e);return t.dispatchEvent(o)}function x(t,e,n){return function(r){return r.addEventListener(t,e,n),r}}var j=ct(),ot=new WeakSet;x.connected=function(t,e){let n="connected";return typeof e!="object"&&(e={}),e.once=!0,function(r){let c="dde:"+n;return r.addEventListener(c,t,e),r.__dde_lifecycleToEvents?r:r.isConnected?(r.dispatchEvent(new Event(c)),r):(C(e.signal,()=>j.offConnected(r,t))&&j.onConnected(r,t),r)}};x.disconnected=function(t,e){let n="disconnected";return typeof e!="object"&&(e={}),e.once=!0,function(r){let c="dde:"+n;return r.addEventListener(c,t,e),r.__dde_lifecycleToEvents||C(e.signal,()=>j.offDisconnected(r,t))&&j.onDisconnected(r,t),r}};x.attributeChanged=function(t,e){let n="attributeChanged";return typeof e!="object"&&(e={}),function(r){let c="dde:"+n;if(r.addEventListener(c,t,e),r.__dde_lifecycleToEvents||ot.has(r))return r;let s=new MutationObserver(function(d){for(let{attributeName:h,target:E}of d)E.dispatchEvent(new CustomEvent(c,{detail:[h,E.getAttribute(h)]}))});return C(e.signal,()=>s.disconnect())&&s.observe(r,{attributes:!0}),r}};function ct(){let t=new Map,e=!1,n=new MutationObserver(function(u){for(let i of u)if(i.type==="childList"){if(h(i.addedNodes,!0)){s();continue}E(i.removedNodes,!0)&&s()}});return{onConnected(u,i){c();let f=r(u);f.connected.has(i)||(f.connected.add(i),f.length_c+=1)},offConnected(u,i){if(!t.has(u))return;let f=t.get(u);f.connected.has(i)&&(f.connected.delete(i),f.length_c-=1,o(u,f))},onDisconnected(u,i){c();let f=r(u);f.disconnected.has(i)||(f.disconnected.add(i),f.length_d+=1)},offDisconnected(u,i){if(!t.has(u))return;let f=t.get(u);f.disconnected.has(i)&&(f.disconnected.delete(i),f.length_d-=1,o(u,f))}};function o(u,i){i.length_c||i.length_d||(t.delete(u),s())}function r(u){if(t.has(u))return t.get(u);let i={connected:new WeakSet,length_c:0,disconnected:new WeakSet,length_d:0};return t.set(u,i),i}function c(){e||(e=!0,n.observe(document.body,{childList:!0,subtree:!0}))}function s(){!e||t.size||(e=!1,n.disconnect())}function a(){return new Promise(function(u){(requestIdleCallback||requestAnimationFrame)(u)})}async function d(u){t.size>30&&await a();let i=[];if(!(u instanceof Node))return i;for(let f of t.keys())f===u||!(f instanceof Node)||u.contains(f)&&i.push(f);return i}function h(u,i){let f=!1;for(let b of u){if(i&&d(b).then(h),!t.has(b))continue;let S=t.get(b);S.length_c&&(b.dispatchEvent(new Event("dde:connected")),S.connected=new WeakSet,S.length_c=0,S.length_d||t.delete(b),f=!0)}return f}function E(u,i){let f=!1;for(let b of u)i&&d(b).then(E),!(!t.has(b)||!t.get(b).length_d)&&(b.dispatchEvent(new Event("dde:disconnected")),t.delete(b),f=!0);return f}}var p=Symbol.for("Signal");function D(t){try{return Reflect.has(t,p)}catch{return!1}}var T=[],l=new WeakMap;function g(t,e){if(typeof t!="function")return V(t,e);if(D(t))return t;let n=V(),o=function(){let[r,...c]=l.get(o);if(l.set(o,new Set([r])),T.push(o),n(t()),T.pop(),!c.length)return;let s=l.get(o);for(let a of c)s.has(a)||O(a,o)};return l.set(n[p],o),l.set(o,new Set([n])),o(),n}g.action=function(t,e,...n){let o=t[p],{actions:r}=o;if(!r||!Reflect.has(r,e))throw new Error(`'${t}' has no action with name '${e}'!`);if(r[e].apply(o,n),o.skip)return Reflect.deleteProperty(o,"skip");o.listeners.forEach(c=>c(o.value))};g.on=function t(e,n,o={}){let{signal:r}=o;if(!(r&&r.aborted)){if(Array.isArray(e))return e.forEach(c=>t(c,n,o));z(e,n),r&&r.addEventListener("abort",()=>O(e,n))}};g.symbols={signal:p,onclear:Symbol.for("Signal.onclear")};var A="__dde_attributes";g.attribute=function(t,e=void 0){let n=g(e),o;return _.host(r=>{if(o=r,r instanceof HTMLElement?r.hasAttribute(t)&&n(r.getAttribute(t)):r.hasAttributeNS(null,t)&&n(r.getAttributeNS(null,t)),r[A]){r[A][t]=n;return}return r[A]={[t]:n},x.attributeChanged(function({detail:s}){/*! This maps attributes to signals (`S.attribute`). -* Investigate `__dde_attributes` key of the element.*/let[a,d]=s,h=r[A][a];if(h)return h(d)})(r),x.disconnected(function(){/*! This removes all signals mapped to attributes (`S.attribute`). -* Investigate `__dde_attributes` key of the element.*/g.clear(...Object.values(r[A])),o=null})(r),r}),new Proxy(n,{apply(r,c,s){if(!s.length)return r();if(!o)return;let a=s[0];return o instanceof HTMLElement?o.setAttribute(t,a):o.setAttributeNS(null,t,a)}})};g.clear=function(...t){for(let n of t){Reflect.deleteProperty(n,"toJSON");let o=n[p];o.onclear.forEach(r=>r.call(o)),e(n,o),Reflect.deleteProperty(n,p)}function e(n,o){o.listeners.forEach(r=>{if(o.listeners.delete(r),!l.has(r))return;let c=l.get(r);c.delete(n),!(c.size>1)&&(g.clear(...c),l.delete(r))})}};var k="__dde_reactive";g.el=function(t,e){let n=m.mark({type:"reactive"},!1),o=n.end,r=document.createDocumentFragment();r.append(n,o);let{current:c}=_,s=a=>{if(!n.parentNode||!o.parentNode)return O(t,s);_.push(c);let d=e(a);_.pop(),Array.isArray(d)||(d=[d]);let h=n;for(;(h=n.nextSibling)!==o;)h.remove();n.after(...d)};return z(t,s),Q(t,s,n,e),s(t()),r};var K={isSignal:D,processReactiveAttribute(t,e,n,o){if(!D(n))return n;let r=c=>o(e,c);return z(n,r),Q(n,r,t,e),n()}};function Q(t,e,...n){let{current:o}=_;o.prevent||o.host(function(r){r[k]||(r[k]=[],x.disconnected(()=>r[k].forEach(([[c,s]])=>O(c,s,c[p]?.host()===r)))(r)),r[k].push([[t,e],...n])})}function V(t,e){let n=(...o)=>o.length?at(n,...o):ft(n);return it(n,t,e)}var st=Object.assign(Object.create(null),{stopPropagation(){this.skip=!0}}),$=class extends Error{constructor(){super();let[e,...n]=this.stack.split(` -`),o=e.slice(e.indexOf("@"),e.indexOf(".js:")+4);this.stack=n.find(r=>!r.includes(o))}};function it(t,e,n){let o=[];F(n)!=="[object Object]"&&(n={});let{onclear:r}=g.symbols;n[r]&&(o.push(n[r]),Reflect.deleteProperty(n,r));let{host:c}=_;return Reflect.defineProperty(t,p,{value:{value:e,actions:n,onclear:o,host:c,listeners:new Set,defined:new $},enumerable:!1,writable:!1,configurable:!0}),t.toJSON=()=>t(),Object.setPrototypeOf(t[p],st),t}function ut(){return T[T.length-1]}function ft(t){if(!t[p])return;let{value:e,listeners:n}=t[p],o=ut();return o&&n.add(o),l.has(o)&&l.get(o).add(t),e}function at(t,e,n){if(!t[p])return;let o=t[p];if(!(!n&&o.value===e))return o.value=e,o.listeners.forEach(r=>r(e)),e}function z(t,e){if(t[p])return t[p].listeners.add(e)}function O(t,e,n){let o=t[p];if(!o)return;let r=o.listeners.delete(e);if(n&&!o.listeners.size){if(g.clear(t),!l.has(o))return r;let c=l.get(o);if(!l.has(c))return r;l.get(c).forEach(s=>O(s,c,!0))}return r}M(K); -globalThis.dde= {S: g, +var y={isSignal(t){return!1},processReactiveAttribute(t,e,n,r){return n}};function M(t,e=!0){return e?Object.assign(y,t):(Object.setPrototypeOf(t,y),t)}function R(t){return y.isPrototypeOf(t)&&t!==y?t:y}function _(t){return typeof t>"u"}function U(t){let e=typeof t;return e!=="object"?e:t===null?"null":Object.prototype.toString.call(t)}function C(t,e){if(!t||!(t instanceof AbortSignal))return!0;if(!t.aborted)return t.addEventListener("abort",e),function(){t.removeEventListener("abort",e)}}var W={setDeleteAttr:X,ssr:!1};function X(t,e,n){if(Reflect.set(t,e,n),!!_(n)){if(Reflect.deleteProperty(t,e),t instanceof HTMLElement&&t.getAttribute(e)==="undefined")return t.removeAttribute(e);if(Reflect.get(t,e)==="undefined")return Reflect.set(t,e,"")}}var w=[{scope:document.body,host:t=>t?t(document.body):document.body,custom_element:!1,prevent:!0}],g={get current(){return w[w.length-1]},get host(){return this.current.host},preventDefault(){let{current:t}=this;return t.prevent=!0,t},get state(){return[...w]},push(t={}){return w.push(Object.assign({},this.current,{prevent:!1},t))},pop(){return w.pop()}},L;function E(t,e,...n){let r=R(this),o=0,c,s;switch((Object(e)!==e||r.isSignal(e))&&(e={textContent:e}),!0){case typeof t=="function":{o=1,g.push({scope:t,host:p=>p?(o===1?n.unshift(p):p(s),void 0):s}),c=t(e||void 0);let a=c instanceof DocumentFragment;if(c.nodeName==="#comment")break;let d=E.mark({type:"component",name:t.name,host:a?"this":"parentElement"});c.prepend(d),a&&(s=d);break}case t==="#text":c=N.call(this,document.createTextNode(""),e);break;case(t==="<>"||!t):c=N.call(this,document.createDocumentFragment(),e);break;case L:c=N.call(this,document.createElementNS(L,t),e);break;case!c:c=N.call(this,document.createElement(t),e)}return rt(c),s||(s=c),n.forEach(a=>a(s)),o&&g.pop(),o=2,c}E.mark=function(t,e=!1){W.ssr&&(t.ssr=!0),t=Object.entries(t).map(([o,c])=>o+`="${c}"`).join(" ");let n=e?"":"/",r=document.createComment(``);return e||(r.end=document.createComment("")),r};E.later=function(){let t=E.mark({type:"later"});return t.append=t.prepend=function(...e){return t.after(...e),t},t};function mt(t){let e=this;return function(...r){L=t;let o=E.call(e,...r);return L=void 0,o}}var{setDeleteAttr:q}=W,j=new WeakMap;function N(t,...e){if(!e.length)return t;j.set(t,J(t,this));for(let[n,r]of Object.entries(Object.assign({},...e)))I.call(this,t,n,r);return j.delete(t),t}function I(t,e,n){let{setRemoveAttr:r,s:o}=J(t,this),c=this;n=o.processReactiveAttribute(t,e,n,(a,d)=>I.call(c,t,a,d));let[s]=e;if(s==="=")return r(e.slice(1),n);if(s===".")return H(t,e.slice(1),n);if(/(aria|data)([A-Z])/.test(e))return e=e.replace(/([a-z])([A-Z])/g,"$1-$2").toLowerCase(),r(e,n);switch(e==="className"&&(e="class"),e){case"xlink:href":return r(e,n,"http://www.w3.org/1999/xlink");case"textContent":return q(t,e,n);case"style":if(typeof n!="object")break;case"dataset":return $(o,n,H.bind(null,t[e]));case"ariaset":return $(o,n,(a,d)=>r("aria-"+a,d));case"classList":return Y.call(c,t,n)}return tt(t,e)?q(t,e,n):r(e,n)}function J(t,e){if(j.has(t))return j.get(t);let r=(t instanceof SVGElement?nt:et).bind(null,t,"Attribute"),o=R(e);return{setRemoveAttr:r,s:o}}function Y(t,e){let n=R(this);return $(n,e,(r,o)=>t.classList.toggle(r,o===-1?void 0:!!o)),t}function _t(t){return Array.from(t.children).forEach(e=>e.remove()),t}function tt(t,e){if(!Reflect.has(t,e))return!1;let n=Z(t,e);return!_(n.set)}function Z(t,e){if(t=Object.getPrototypeOf(t),!t)return{};let n=Object.getOwnPropertyDescriptor(t,e);return n||Z(t,e)}function $(t,e,n){if(!(typeof e!="object"||e===null))return Object.entries(e).forEach(function([o,c]){o&&(c=t.processReactiveAttribute(e,o,c,n),n(o,c))})}function G(t){return Array.isArray(t)?t.filter(Boolean).join(" "):t}function et(t,e,n,r){return t[(_(r)?"remove":"set")+e](n,G(r))}function nt(t,e,n,r,o=null){return t[(_(r)?"remove":"set")+e+"NS"](o,n,G(r))}function H(t,e,n){if(Reflect.set(t,e,n),!!_(n))return Reflect.deleteProperty(t,e)}function B(...t){return this.appendOrig(...t),this}function rt(t){return t.append===B||(t.appendOrig=t.append,t.append=B),t}function xt(t,e,...n){let r=n.length?new CustomEvent(e,{detail:n[0]}):new Event(e);return t.dispatchEvent(r)}function v(t,e,n){return function(o){return o.addEventListener(t,e,n),o}}var P=ct(),ot=new WeakSet;v.connected=function(t,e){let{custom_element:n}=g.current,r="connected";return typeof e!="object"&&(e={}),e.once=!0,function(c){n&&(c=n);let s="dde:"+r;return c.addEventListener(s,t,e),c.__dde_lifecycleToEvents?c:c.isConnected?(c.dispatchEvent(new Event(s)),c):(C(e.signal,()=>P.offConnected(c,t))&&P.onConnected(c,t),c)}};v.disconnected=function(t,e){let{custom_element:n}=g.current,r="disconnected";return typeof e!="object"&&(e={}),e.once=!0,function(c){n&&(c=n);let s="dde:"+r;return c.addEventListener(s,t,e),c.__dde_lifecycleToEvents||C(e.signal,()=>P.offDisconnected(c,t))&&P.onDisconnected(c,t),c}};v.attributeChanged=function(t,e){let n="attributeChanged";return typeof e!="object"&&(e={}),function(o){let c="dde:"+n;if(o.addEventListener(c,t,e),o.__dde_lifecycleToEvents||ot.has(o))return o;let s=new MutationObserver(function(d){for(let{attributeName:p,target:x}of d)x.dispatchEvent(new CustomEvent(c,{detail:[p,x.getAttribute(p)]}))});return C(e.signal,()=>s.disconnect())&&s.observe(o,{attributes:!0}),o}};function ct(){let t=new Map,e=!1,n=new MutationObserver(function(i){for(let u of i)if(u.type==="childList"){if(p(u.addedNodes,!0)){s();continue}x(u.removedNodes,!0)&&s()}});return{onConnected(i,u){c();let f=o(i);f.connected.has(u)||(f.connected.add(u),f.length_c+=1)},offConnected(i,u){if(!t.has(i))return;let f=t.get(i);f.connected.has(u)&&(f.connected.delete(u),f.length_c-=1,r(i,f))},onDisconnected(i,u){c();let f=o(i);f.disconnected.has(u)||(f.disconnected.add(u),f.length_d+=1)},offDisconnected(i,u){if(!t.has(i))return;let f=t.get(i);f.disconnected.has(u)&&(f.disconnected.delete(u),f.length_d-=1,r(i,f))}};function r(i,u){u.length_c||u.length_d||(t.delete(i),s())}function o(i){if(t.has(i))return t.get(i);let u={connected:new WeakSet,length_c:0,disconnected:new WeakSet,length_d:0};return t.set(i,u),u}function c(){e||(e=!0,n.observe(document.body,{childList:!0,subtree:!0}))}function s(){!e||t.size||(e=!1,n.disconnect())}function a(){return new Promise(function(i){(requestIdleCallback||requestAnimationFrame)(i)})}async function d(i){t.size>30&&await a();let u=[];if(!(i instanceof Node))return u;for(let f of t.keys())f===i||!(f instanceof Node)||i.contains(f)&&u.push(f);return u}function p(i,u){let f=!1;for(let m of i){if(u&&d(m).then(p),!t.has(m))continue;let S=t.get(m);S.length_c&&(m.dispatchEvent(new Event("dde:connected")),S.connected=new WeakSet,S.length_c=0,S.length_d||t.delete(m),f=!0)}return f}function x(i,u){let f=!1;for(let m of i)u&&d(m).then(x),!(!t.has(m)||!t.get(m).length_d)&&(m.dispatchEvent(new Event("dde:disconnected")),t.delete(m),f=!0);return f}}var l=Symbol.for("Signal");function D(t){try{return Reflect.has(t,l)}catch{return!1}}var T=[],h=new WeakMap;function b(t,e){if(typeof t!="function")return V(t,e);if(D(t))return t;let n=V(),r=function(){let[o,...c]=h.get(r);if(h.set(r,new Set([o])),T.push(r),n(t()),T.pop(),!c.length)return;let s=h.get(r);for(let a of c)s.has(a)||O(a,r)};return h.set(n[l],r),h.set(r,new Set([n])),r(),n}b.action=function(t,e,...n){let r=t[l],{actions:o}=r;if(!o||!Reflect.has(o,e))throw new Error(`'${t}' has no action with name '${e}'!`);if(o[e].apply(r,n),r.skip)return Reflect.deleteProperty(r,"skip");r.listeners.forEach(c=>c(r.value))};b.on=function t(e,n,r={}){let{signal:o}=r;if(!(o&&o.aborted)){if(Array.isArray(e))return e.forEach(c=>t(c,n,r));F(e,n),o&&o.addEventListener("abort",()=>O(e,n))}};b.symbols={signal:l,onclear:Symbol.for("Signal.onclear")};var A="__dde_attributes";b.attribute=function(t,e=void 0){let n=b(e),r;return g.host(o=>{if(r=o,o instanceof HTMLElement?o.hasAttribute(t)&&n(o.getAttribute(t)):o.hasAttributeNS(null,t)&&n(o.getAttributeNS(null,t)),o[A]){o[A][t]=n;return}return o[A]={[t]:n},v.attributeChanged(function({detail:s}){/*! This maps attributes to signals (`S.attribute`). +* Investigate `__dde_attributes` key of the element.*/let[a,d]=s,p=o[A][a];if(p)return p(d)})(o),v.disconnected(function(){/*! This removes all signals mapped to attributes (`S.attribute`). +* Investigate `__dde_attributes` key of the element.*/b.clear(...Object.values(o[A])),r=null})(o),o}),new Proxy(n,{apply(o,c,s){if(!s.length)return o();if(!r)return;let a=s[0];return r instanceof HTMLElement?r.setAttribute(t,a):r.setAttributeNS(null,t,a)}})};b.clear=function(...t){for(let n of t){Reflect.deleteProperty(n,"toJSON");let r=n[l];r.onclear.forEach(o=>o.call(r)),e(n,r),Reflect.deleteProperty(n,l)}function e(n,r){r.listeners.forEach(o=>{if(r.listeners.delete(o),!h.has(o))return;let c=h.get(o);c.delete(n),!(c.size>1)&&(b.clear(...c),h.delete(o))})}};var k="__dde_reactive";b.el=function(t,e){let n=E.mark({type:"reactive"},!1),r=n.end,o=document.createDocumentFragment();o.append(n,r);let{current:c}=g,s=a=>{if(!n.parentNode||!r.parentNode)return O(t,s);g.push(c);let d=e(a);g.pop(),Array.isArray(d)||(d=[d]);let p=n;for(;(p=n.nextSibling)!==r;)p.remove();n.after(...d)};return F(t,s),Q(t,s,n,e),s(t()),o};var K={isSignal:D,processReactiveAttribute(t,e,n,r){if(!D(n))return n;let o=c=>r(e,c);return F(n,o),Q(n,o,t,e),n()}};function Q(t,e,...n){let{current:r}=g;r.prevent||r.host(function(o){o[k]||(o[k]=[],v.disconnected(()=>o[k].forEach(([[c,s]])=>O(c,s,c[l]?.host()===o)))(o)),o[k].push([[t,e],...n])})}function V(t,e){let n=(...r)=>r.length?at(n,...r):ft(n);return it(n,t,e)}var st=Object.assign(Object.create(null),{stopPropagation(){this.skip=!0}}),z=class extends Error{constructor(){super();let[e,...n]=this.stack.split(` +`),r=e.slice(e.indexOf("@"),e.indexOf(".js:")+4);this.stack=n.find(o=>!o.includes(r))}};function it(t,e,n){let r=[];U(n)!=="[object Object]"&&(n={});let{onclear:o}=b.symbols;n[o]&&(r.push(n[o]),Reflect.deleteProperty(n,o));let{host:c}=g;return Reflect.defineProperty(t,l,{value:{value:e,actions:n,onclear:r,host:c,listeners:new Set,defined:new z},enumerable:!1,writable:!1,configurable:!0}),t.toJSON=()=>t(),Object.setPrototypeOf(t[l],st),t}function ut(){return T[T.length-1]}function ft(t){if(!t[l])return;let{value:e,listeners:n}=t[l],r=ut();return r&&n.add(r),h.has(r)&&h.get(r).add(t),e}function at(t,e,n){if(!t[l])return;let r=t[l];if(!(!n&&r.value===e))return r.value=e,r.listeners.forEach(o=>o(e)),e}function F(t,e){if(t[l])return t[l].listeners.add(e)}function O(t,e,n){let r=t[l];if(!r)return;let o=r.listeners.delete(e);if(n&&!r.listeners.size){if(b.clear(t),!h.has(r))return o;let c=h.get(r);if(!h.has(c))return o;h.get(c).forEach(s=>O(s,c,!0))}return o}M(K); +globalThis.dde= {S: b, assign: N, assignAttribute: I, classListDeclarative: Y, -createElement: m, -createElementNS: bt, +createElement: E, +createElementNS: mt, dispatchEvent: xt, -el: m, -elNS: bt, -empty: Et, +el: E, +elNS: mt, +empty: _t, isSignal: D, -on: x, +on: v, registerReactivity: M, -scope: _ +scope: g }; })(); \ No newline at end of file diff --git a/dist/dde.js b/dist/dde.js index a95571d..afbc2ea 100644 --- a/dist/dde.js +++ b/dist/dde.js @@ -1,18 +1,18 @@ //deka-dom-el library is available via global namespace `dde` (()=> { -var m={isSignal(t){return!1},processReactiveAttribute(t,e,n,o){return n}};function $(t,e=!0){return e?Object.assign(m,t):(Object.setPrototypeOf(t,m),t)}function _(t){return m.isPrototypeOf(t)&&t!==m?t:m}function g(t){return typeof t>"u"}function x(t,e){if(!t||!(t instanceof AbortSignal))return!0;if(!t.aborted)return t.addEventListener("abort",e),function(){t.removeEventListener("abort",e)}}var L={setDeleteAttr:U};function U(t,e,n){if(Reflect.set(t,e,n),!!g(n)){if(Reflect.deleteProperty(t,e),t instanceof HTMLElement&&t.getAttribute(e)==="undefined")return t.removeAttribute(e);if(Reflect.get(t,e)==="undefined")return Reflect.set(t,e,"")}}var v=[{scope:document.body,host:t=>t?t(document.body):document.body,prevent:!0,inherit_host:!1}],S={get current(){return v[v.length-1]},get host(){return this.current.host},preventDefault(){let{current:t}=this;return t.prevent=!0,t},get state(){return[...v]},push(t={}){return v.push(Object.assign({},this.current,{prevent:!1},t))},pop(){return v.pop()}},A;function E(t,e,...n){let o=_(this),r=0,s,f;switch((Object(e)!==e||o.isSignal(e))&&(e={textContent:e}),!0){case typeof t=="function":{r=1;let{inherit_host:d,host:p}=S.current,l=d?p:c=>c?(r===1?n.unshift(c):c(f),void 0):f;S.push({scope:t,host:l,inherit_host:d}),s=t(e||void 0);let h=s instanceof DocumentFragment,i=E.mark({type:"component",name:t.name,host:h?"this":s.nodeName==="#comment"?"previousLater":"parentElement"});s.prepend(i),h&&(f=i);break}case t==="#text":s=w.call(this,document.createTextNode(""),e);break;case(t==="<>"||!t):s=w.call(this,document.createDocumentFragment(),e);break;case A:s=w.call(this,document.createElementNS(A,t),e);break;case!s:s=w.call(this,document.createElement(t),e)}return B(s),f||(f=s),n.forEach(d=>d(f)),r&&S.pop(),r=2,s}E.mark=function(t,e=!1){t=Object.entries(t).map(([r,s])=>r+`="${s}"`).join(" ");let n=e?"":"/",o=document.createComment(``);return e||(o.end=document.createComment("")),o};E.later=function(){let t=E.mark({type:"later"});return t.append=t.prepend=function(...e){return t.after(...e),t},t};function Q(t){let e=this;return function(...o){A=t;let r=E.call(e,...o);return A=void 0,r}}var{setDeleteAttr:N}=L,O=new WeakMap;function w(t,...e){if(!e.length)return t;O.set(t,T(t,this));for(let[n,o]of Object.entries(Object.assign({},...e)))P.call(this,t,n,o);return O.delete(t),t}function P(t,e,n){let{setRemoveAttr:o,s:r}=T(t,this),s=this;n=r.processReactiveAttribute(t,e,n,(d,p)=>P.call(s,t,d,p));let[f]=e;if(f==="=")return o(e.slice(1),n);if(f===".")return D(t,e.slice(1),n);if(/(aria|data)([A-Z])/.test(e))return e=e.replace(/([a-z])([A-Z])/g,"$1-$2").toLowerCase(),o(e,n);switch(e==="className"&&(e="class"),e){case"xlink:href":return o(e,n,"http://www.w3.org/1999/xlink");case"textContent":return N(t,e,n);case"style":if(typeof n!="object")break;case"dataset":return R(r,n,D.bind(null,t[e]));case"ariaset":return R(r,n,(d,p)=>o("aria-"+d,p));case"classList":return q.call(s,t,n)}return z(t,e)?N(t,e,n):o(e,n)}function T(t,e){if(O.has(t))return O.get(t);let o=(t instanceof SVGElement?k:F).bind(null,t,"Attribute"),r=_(e);return{setRemoveAttr:o,s:r}}function q(t,e){let n=_(this);return R(n,e,(o,r)=>t.classList.toggle(o,r===-1?void 0:!!r)),t}function Y(t){return Array.from(t.children).forEach(e=>e.remove()),t}function z(t,e){if(!Reflect.has(t,e))return!1;let n=W(t,e);return!g(n.set)}function W(t,e){if(t=Object.getPrototypeOf(t),!t)return{};let n=Object.getOwnPropertyDescriptor(t,e);return n||W(t,e)}function R(t,e,n){if(!(typeof e!="object"||e===null))return Object.entries(e).forEach(function([r,s]){r&&(s=t.processReactiveAttribute(e,r,s,n),n(r,s))})}function M(t){return Array.isArray(t)?t.filter(Boolean).join(" "):t}function F(t,e,n,o){return t[(g(o)?"remove":"set")+e](n,M(o))}function k(t,e,n,o,r=null){return t[(g(o)?"remove":"set")+e+"NS"](r,n,M(o))}function D(t,e,n){if(Reflect.set(t,e,n),!!g(n))return Reflect.deleteProperty(t,e)}function j(...t){return this.appendOrig(...t),this}function B(t){return t.append===j||(t.appendOrig=t.append,t.append=j),t}function nt(t,e,...n){let o=n.length?new CustomEvent(e,{detail:n[0]}):new Event(e);return t.dispatchEvent(o)}function y(t,e,n){return function(r){return r.addEventListener(t,e,n),r}}var C=Z(),I=new WeakSet;y.connected=function(t,e){let n="connected";return typeof e!="object"&&(e={}),e.once=!0,function(r){let s="dde:"+n;return r.addEventListener(s,t,e),r.__dde_lifecycleToEvents?r:r.isConnected?(r.dispatchEvent(new Event(s)),r):(x(e.signal,()=>C.offConnected(r,t))&&C.onConnected(r,t),r)}};y.disconnected=function(t,e){let n="disconnected";return typeof e!="object"&&(e={}),e.once=!0,function(r){let s="dde:"+n;return r.addEventListener(s,t,e),r.__dde_lifecycleToEvents||x(e.signal,()=>C.offDisconnected(r,t))&&C.onDisconnected(r,t),r}};y.attributeChanged=function(t,e){let n="attributeChanged";return typeof e!="object"&&(e={}),function(r){let s="dde:"+n;if(r.addEventListener(s,t,e),r.__dde_lifecycleToEvents||I.has(r))return r;let f=new MutationObserver(function(p){for(let{attributeName:l,target:h}of p)h.dispatchEvent(new CustomEvent(s,{detail:[l,h.getAttribute(l)]}))});return x(e.signal,()=>f.disconnect())&&f.observe(r,{attributes:!0}),r}};function Z(){let t=new Map,e=!1,n=new MutationObserver(function(i){for(let c of i)if(c.type==="childList"){if(l(c.addedNodes,!0)){f();continue}h(c.removedNodes,!0)&&f()}});return{onConnected(i,c){s();let u=r(i);u.connected.has(c)||(u.connected.add(c),u.length_c+=1)},offConnected(i,c){if(!t.has(i))return;let u=t.get(i);u.connected.has(c)&&(u.connected.delete(c),u.length_c-=1,o(i,u))},onDisconnected(i,c){s();let u=r(i);u.disconnected.has(c)||(u.disconnected.add(c),u.length_d+=1)},offDisconnected(i,c){if(!t.has(i))return;let u=t.get(i);u.disconnected.has(c)&&(u.disconnected.delete(c),u.length_d-=1,o(i,u))}};function o(i,c){c.length_c||c.length_d||(t.delete(i),f())}function r(i){if(t.has(i))return t.get(i);let c={connected:new WeakSet,length_c:0,disconnected:new WeakSet,length_d:0};return t.set(i,c),c}function s(){e||(e=!0,n.observe(document.body,{childList:!0,subtree:!0}))}function f(){!e||t.size||(e=!1,n.disconnect())}function d(){return new Promise(function(i){(requestIdleCallback||requestAnimationFrame)(i)})}async function p(i){t.size>30&&await d();let c=[];if(!(i instanceof Node))return c;for(let u of t.keys())u===i||!(u instanceof Node)||i.contains(u)&&c.push(u);return c}function l(i,c){let u=!1;for(let a of i){if(c&&p(a).then(l),!t.has(a))continue;let b=t.get(a);b.length_c&&(a.dispatchEvent(new Event("dde:connected")),b.connected=new WeakSet,b.length_c=0,b.length_d||t.delete(a),u=!0)}return u}function h(i,c){let u=!1;for(let a of i)c&&p(a).then(h),!(!t.has(a)||!t.get(a).length_d)&&(a.dispatchEvent(new Event("dde:disconnected")),t.delete(a),u=!0);return u}} -globalThis.dde= {assign: w, +var b={isSignal(t){return!1},processReactiveAttribute(t,e,n,c){return n}};function $(t,e=!0){return e?Object.assign(b,t):(Object.setPrototypeOf(t,b),t)}function x(t){return b.isPrototypeOf(t)&&t!==b?t:b}function l(t){return typeof t>"u"}function w(t,e){if(!t||!(t instanceof AbortSignal))return!0;if(!t.aborted)return t.addEventListener("abort",e),function(){t.removeEventListener("abort",e)}}var R={setDeleteAttr:U,ssr:!1};function U(t,e,n){if(Reflect.set(t,e,n),!!l(n)){if(Reflect.deleteProperty(t,e),t instanceof HTMLElement&&t.getAttribute(e)==="undefined")return t.removeAttribute(e);if(Reflect.get(t,e)==="undefined")return Reflect.set(t,e,"")}}var v=[{scope:document.body,host:t=>t?t(document.body):document.body,custom_element:!1,prevent:!0}],E={get current(){return v[v.length-1]},get host(){return this.current.host},preventDefault(){let{current:t}=this;return t.prevent=!0,t},get state(){return[...v]},push(t={}){return v.push(Object.assign({},this.current,{prevent:!1},t))},pop(){return v.pop()}},O;function _(t,e,...n){let c=x(this),o=0,r,f;switch((Object(e)!==e||c.isSignal(e))&&(e={textContent:e}),!0){case typeof t=="function":{o=1,E.push({scope:t,host:h=>h?(o===1?n.unshift(h):h(f),void 0):f}),r=t(e||void 0);let d=r instanceof DocumentFragment;if(r.nodeName==="#comment")break;let a=_.mark({type:"component",name:t.name,host:d?"this":"parentElement"});r.prepend(a),d&&(f=a);break}case t==="#text":r=A.call(this,document.createTextNode(""),e);break;case(t==="<>"||!t):r=A.call(this,document.createDocumentFragment(),e);break;case O:r=A.call(this,document.createElementNS(O,t),e);break;case!r:r=A.call(this,document.createElement(t),e)}return B(r),f||(f=r),n.forEach(d=>d(f)),o&&E.pop(),o=2,r}_.mark=function(t,e=!1){R.ssr&&(t.ssr=!0),t=Object.entries(t).map(([o,r])=>o+`="${r}"`).join(" ");let n=e?"":"/",c=document.createComment(``);return e||(c.end=document.createComment("")),c};_.later=function(){let t=_.mark({type:"later"});return t.append=t.prepend=function(...e){return t.after(...e),t},t};function X(t){let e=this;return function(...c){O=t;let o=_.call(e,...c);return O=void 0,o}}var{setDeleteAttr:D}=R,C=new WeakMap;function A(t,...e){if(!e.length)return t;C.set(t,T(t,this));for(let[n,c]of Object.entries(Object.assign({},...e)))P.call(this,t,n,c);return C.delete(t),t}function P(t,e,n){let{setRemoveAttr:c,s:o}=T(t,this),r=this;n=o.processReactiveAttribute(t,e,n,(d,a)=>P.call(r,t,d,a));let[f]=e;if(f==="=")return c(e.slice(1),n);if(f===".")return L(t,e.slice(1),n);if(/(aria|data)([A-Z])/.test(e))return e=e.replace(/([a-z])([A-Z])/g,"$1-$2").toLowerCase(),c(e,n);switch(e==="className"&&(e="class"),e){case"xlink:href":return c(e,n,"http://www.w3.org/1999/xlink");case"textContent":return D(t,e,n);case"style":if(typeof n!="object")break;case"dataset":return y(o,n,L.bind(null,t[e]));case"ariaset":return y(o,n,(d,a)=>c("aria-"+d,a));case"classList":return k.call(r,t,n)}return q(t,e)?D(t,e,n):c(e,n)}function T(t,e){if(C.has(t))return C.get(t);let c=(t instanceof SVGElement?F:z).bind(null,t,"Attribute"),o=x(e);return{setRemoveAttr:c,s:o}}function k(t,e){let n=x(this);return y(n,e,(c,o)=>t.classList.toggle(c,o===-1?void 0:!!o)),t}function Y(t){return Array.from(t.children).forEach(e=>e.remove()),t}function q(t,e){if(!Reflect.has(t,e))return!1;let n=W(t,e);return!l(n.set)}function W(t,e){if(t=Object.getPrototypeOf(t),!t)return{};let n=Object.getOwnPropertyDescriptor(t,e);return n||W(t,e)}function y(t,e,n){if(!(typeof e!="object"||e===null))return Object.entries(e).forEach(function([o,r]){o&&(r=t.processReactiveAttribute(e,o,r,n),n(o,r))})}function M(t){return Array.isArray(t)?t.filter(Boolean).join(" "):t}function z(t,e,n,c){return t[(l(c)?"remove":"set")+e](n,M(c))}function F(t,e,n,c,o=null){return t[(l(c)?"remove":"set")+e+"NS"](o,n,M(c))}function L(t,e,n){if(Reflect.set(t,e,n),!!l(n))return Reflect.deleteProperty(t,e)}function j(...t){return this.appendOrig(...t),this}function B(t){return t.append===j||(t.appendOrig=t.append,t.append=j),t}function nt(t,e,...n){let c=n.length?new CustomEvent(e,{detail:n[0]}):new Event(e);return t.dispatchEvent(c)}function N(t,e,n){return function(o){return o.addEventListener(t,e,n),o}}var S=Z(),I=new WeakSet;N.connected=function(t,e){let{custom_element:n}=E.current,c="connected";return typeof e!="object"&&(e={}),e.once=!0,function(r){n&&(r=n);let f="dde:"+c;return r.addEventListener(f,t,e),r.__dde_lifecycleToEvents?r:r.isConnected?(r.dispatchEvent(new Event(f)),r):(w(e.signal,()=>S.offConnected(r,t))&&S.onConnected(r,t),r)}};N.disconnected=function(t,e){let{custom_element:n}=E.current,c="disconnected";return typeof e!="object"&&(e={}),e.once=!0,function(r){n&&(r=n);let f="dde:"+c;return r.addEventListener(f,t,e),r.__dde_lifecycleToEvents||w(e.signal,()=>S.offDisconnected(r,t))&&S.onDisconnected(r,t),r}};N.attributeChanged=function(t,e){let n="attributeChanged";return typeof e!="object"&&(e={}),function(o){let r="dde:"+n;if(o.addEventListener(r,t,e),o.__dde_lifecycleToEvents||I.has(o))return o;let f=new MutationObserver(function(a){for(let{attributeName:h,target:g}of a)g.dispatchEvent(new CustomEvent(r,{detail:[h,g.getAttribute(h)]}))});return w(e.signal,()=>f.disconnect())&&f.observe(o,{attributes:!0}),o}};function Z(){let t=new Map,e=!1,n=new MutationObserver(function(s){for(let i of s)if(i.type==="childList"){if(h(i.addedNodes,!0)){f();continue}g(i.removedNodes,!0)&&f()}});return{onConnected(s,i){r();let u=o(s);u.connected.has(i)||(u.connected.add(i),u.length_c+=1)},offConnected(s,i){if(!t.has(s))return;let u=t.get(s);u.connected.has(i)&&(u.connected.delete(i),u.length_c-=1,c(s,u))},onDisconnected(s,i){r();let u=o(s);u.disconnected.has(i)||(u.disconnected.add(i),u.length_d+=1)},offDisconnected(s,i){if(!t.has(s))return;let u=t.get(s);u.disconnected.has(i)&&(u.disconnected.delete(i),u.length_d-=1,c(s,u))}};function c(s,i){i.length_c||i.length_d||(t.delete(s),f())}function o(s){if(t.has(s))return t.get(s);let i={connected:new WeakSet,length_c:0,disconnected:new WeakSet,length_d:0};return t.set(s,i),i}function r(){e||(e=!0,n.observe(document.body,{childList:!0,subtree:!0}))}function f(){!e||t.size||(e=!1,n.disconnect())}function d(){return new Promise(function(s){(requestIdleCallback||requestAnimationFrame)(s)})}async function a(s){t.size>30&&await d();let i=[];if(!(s instanceof Node))return i;for(let u of t.keys())u===s||!(u instanceof Node)||s.contains(u)&&i.push(u);return i}function h(s,i){let u=!1;for(let p of s){if(i&&a(p).then(h),!t.has(p))continue;let m=t.get(p);m.length_c&&(p.dispatchEvent(new Event("dde:connected")),m.connected=new WeakSet,m.length_c=0,m.length_d||t.delete(p),u=!0)}return u}function g(s,i){let u=!1;for(let p of s)i&&a(p).then(g),!(!t.has(p)||!t.get(p).length_d)&&(p.dispatchEvent(new Event("dde:disconnected")),t.delete(p),u=!0);return u}} +globalThis.dde= {assign: A, assignAttribute: P, -classListDeclarative: q, -createElement: E, -createElementNS: Q, +classListDeclarative: k, +createElement: _, +createElementNS: X, dispatchEvent: nt, -el: E, -elNS: Q, +el: _, +elNS: X, empty: Y, -on: y, +on: N, registerReactivity: $, -scope: S +scope: E }; })(); \ No newline at end of file diff --git a/dist/esm-with-signals.d.ts b/dist/esm-with-signals.d.ts index d0ff587..4436a69 100644 --- a/dist/esm-with-signals.d.ts +++ b/dist/esm-with-signals.d.ts @@ -121,7 +121,7 @@ interface On{ ) : EE; } export const on: On; -type Scope= { scope: Node | Function | Object, host: ddeElementModifier, prevent: boolean, inherit_host: boolean, } +type Scope= { scope: Node | Function | Object, host: ddeElementModifier, custom_element: false | HTMLElement, prevent: boolean } /** Current scope created last time the `el(Function)` was invoke. (Or {@link scope.push}) */ export const scope: { current: Scope, @@ -431,6 +431,10 @@ declare global{ /** Elements returned by {@link el} return parent element for `.append` method. **Regullarly created elements are untouched.** */ append: ddeAppend; } + interface SVGElement{ + /** Elements returned by {@link el} return parent element for `.append` method. **Regullarly created elements are untouched.** */ + append: ddeAppend; + } } export type Signal= (set?: V)=> V & A; type Action= (this: { value: V }, ...a: any[])=> typeof S._ | void; diff --git a/dist/esm-with-signals.js b/dist/esm-with-signals.js index 03e9948..6a5a123 100644 --- a/dist/esm-with-signals.js +++ b/dist/esm-with-signals.js @@ -1,4 +1,4 @@ -var y={isSignal(t){return!1},processReactiveAttribute(t,e,n,o){return n}};function M(t,e=!0){return e?Object.assign(y,t):(Object.setPrototypeOf(t,y),t)}function R(t){return y.isPrototypeOf(t)&&t!==y?t:y}function v(t){return typeof t>"u"}function F(t){let e=typeof t;return e!=="object"?e:t===null?"null":Object.prototype.toString.call(t)}function C(t,e){if(!t||!(t instanceof AbortSignal))return!0;if(!t.aborted)return t.addEventListener("abort",e),function(){t.removeEventListener("abort",e)}}var U={setDeleteAttr:X};function X(t,e,n){if(Reflect.set(t,e,n),!!v(n)){if(Reflect.deleteProperty(t,e),t instanceof HTMLElement&&t.getAttribute(e)==="undefined")return t.removeAttribute(e);if(Reflect.get(t,e)==="undefined")return Reflect.set(t,e,"")}}var w=[{scope:document.body,host:t=>t?t(document.body):document.body,prevent:!0,inherit_host:!1}],_={get current(){return w[w.length-1]},get host(){return this.current.host},preventDefault(){let{current:t}=this;return t.prevent=!0,t},get state(){return[...w]},push(t={}){return w.push(Object.assign({},this.current,{prevent:!1},t))},pop(){return w.pop()}},L;function m(t,e,...n){let o=R(this),r=0,c,s;switch((Object(e)!==e||o.isSignal(e))&&(e={textContent:e}),!0){case typeof t=="function":{r=1;let{inherit_host:a,host:d}=_.current,h=a?d:i=>i?(r===1?n.unshift(i):i(s),void 0):s;_.push({scope:t,host:h,inherit_host:a}),c=t(e||void 0);let E=c instanceof DocumentFragment,u=m.mark({type:"component",name:t.name,host:E?"this":c.nodeName==="#comment"?"previousLater":"parentElement"});c.prepend(u),E&&(s=u);break}case t==="#text":c=N.call(this,document.createTextNode(""),e);break;case(t==="<>"||!t):c=N.call(this,document.createDocumentFragment(),e);break;case L:c=N.call(this,document.createElementNS(L,t),e);break;case!c:c=N.call(this,document.createElement(t),e)}return rt(c),s||(s=c),n.forEach(a=>a(s)),r&&_.pop(),r=2,c}m.mark=function(t,e=!1){t=Object.entries(t).map(([r,c])=>r+`="${c}"`).join(" ");let n=e?"":"/",o=document.createComment(``);return e||(o.end=document.createComment("")),o};m.later=function(){let t=m.mark({type:"later"});return t.append=t.prepend=function(...e){return t.after(...e),t},t};function bt(t){let e=this;return function(...o){L=t;let r=m.call(e,...o);return L=void 0,r}}var{setDeleteAttr:q}=U,P=new WeakMap;function N(t,...e){if(!e.length)return t;P.set(t,J(t,this));for(let[n,o]of Object.entries(Object.assign({},...e)))I.call(this,t,n,o);return P.delete(t),t}function I(t,e,n){let{setRemoveAttr:o,s:r}=J(t,this),c=this;n=r.processReactiveAttribute(t,e,n,(a,d)=>I.call(c,t,a,d));let[s]=e;if(s==="=")return o(e.slice(1),n);if(s===".")return H(t,e.slice(1),n);if(/(aria|data)([A-Z])/.test(e))return e=e.replace(/([a-z])([A-Z])/g,"$1-$2").toLowerCase(),o(e,n);switch(e==="className"&&(e="class"),e){case"xlink:href":return o(e,n,"http://www.w3.org/1999/xlink");case"textContent":return q(t,e,n);case"style":if(typeof n!="object")break;case"dataset":return W(r,n,H.bind(null,t[e]));case"ariaset":return W(r,n,(a,d)=>o("aria-"+a,d));case"classList":return Y.call(c,t,n)}return tt(t,e)?q(t,e,n):o(e,n)}function J(t,e){if(P.has(t))return P.get(t);let o=(t instanceof SVGElement?nt:et).bind(null,t,"Attribute"),r=R(e);return{setRemoveAttr:o,s:r}}function Y(t,e){let n=R(this);return W(n,e,(o,r)=>t.classList.toggle(o,r===-1?void 0:!!r)),t}function Et(t){return Array.from(t.children).forEach(e=>e.remove()),t}function tt(t,e){if(!Reflect.has(t,e))return!1;let n=Z(t,e);return!v(n.set)}function Z(t,e){if(t=Object.getPrototypeOf(t),!t)return{};let n=Object.getOwnPropertyDescriptor(t,e);return n||Z(t,e)}function W(t,e,n){if(!(typeof e!="object"||e===null))return Object.entries(e).forEach(function([r,c]){r&&(c=t.processReactiveAttribute(e,r,c,n),n(r,c))})}function G(t){return Array.isArray(t)?t.filter(Boolean).join(" "):t}function et(t,e,n,o){return t[(v(o)?"remove":"set")+e](n,G(o))}function nt(t,e,n,o,r=null){return t[(v(o)?"remove":"set")+e+"NS"](r,n,G(o))}function H(t,e,n){if(Reflect.set(t,e,n),!!v(n))return Reflect.deleteProperty(t,e)}function B(...t){return this.appendOrig(...t),this}function rt(t){return t.append===B||(t.appendOrig=t.append,t.append=B),t}function xt(t,e,...n){let o=n.length?new CustomEvent(e,{detail:n[0]}):new Event(e);return t.dispatchEvent(o)}function x(t,e,n){return function(r){return r.addEventListener(t,e,n),r}}var j=ct(),ot=new WeakSet;x.connected=function(t,e){let n="connected";return typeof e!="object"&&(e={}),e.once=!0,function(r){let c="dde:"+n;return r.addEventListener(c,t,e),r.__dde_lifecycleToEvents?r:r.isConnected?(r.dispatchEvent(new Event(c)),r):(C(e.signal,()=>j.offConnected(r,t))&&j.onConnected(r,t),r)}};x.disconnected=function(t,e){let n="disconnected";return typeof e!="object"&&(e={}),e.once=!0,function(r){let c="dde:"+n;return r.addEventListener(c,t,e),r.__dde_lifecycleToEvents||C(e.signal,()=>j.offDisconnected(r,t))&&j.onDisconnected(r,t),r}};x.attributeChanged=function(t,e){let n="attributeChanged";return typeof e!="object"&&(e={}),function(r){let c="dde:"+n;if(r.addEventListener(c,t,e),r.__dde_lifecycleToEvents||ot.has(r))return r;let s=new MutationObserver(function(d){for(let{attributeName:h,target:E}of d)E.dispatchEvent(new CustomEvent(c,{detail:[h,E.getAttribute(h)]}))});return C(e.signal,()=>s.disconnect())&&s.observe(r,{attributes:!0}),r}};function ct(){let t=new Map,e=!1,n=new MutationObserver(function(u){for(let i of u)if(i.type==="childList"){if(h(i.addedNodes,!0)){s();continue}E(i.removedNodes,!0)&&s()}});return{onConnected(u,i){c();let f=r(u);f.connected.has(i)||(f.connected.add(i),f.length_c+=1)},offConnected(u,i){if(!t.has(u))return;let f=t.get(u);f.connected.has(i)&&(f.connected.delete(i),f.length_c-=1,o(u,f))},onDisconnected(u,i){c();let f=r(u);f.disconnected.has(i)||(f.disconnected.add(i),f.length_d+=1)},offDisconnected(u,i){if(!t.has(u))return;let f=t.get(u);f.disconnected.has(i)&&(f.disconnected.delete(i),f.length_d-=1,o(u,f))}};function o(u,i){i.length_c||i.length_d||(t.delete(u),s())}function r(u){if(t.has(u))return t.get(u);let i={connected:new WeakSet,length_c:0,disconnected:new WeakSet,length_d:0};return t.set(u,i),i}function c(){e||(e=!0,n.observe(document.body,{childList:!0,subtree:!0}))}function s(){!e||t.size||(e=!1,n.disconnect())}function a(){return new Promise(function(u){(requestIdleCallback||requestAnimationFrame)(u)})}async function d(u){t.size>30&&await a();let i=[];if(!(u instanceof Node))return i;for(let f of t.keys())f===u||!(f instanceof Node)||u.contains(f)&&i.push(f);return i}function h(u,i){let f=!1;for(let b of u){if(i&&d(b).then(h),!t.has(b))continue;let S=t.get(b);S.length_c&&(b.dispatchEvent(new Event("dde:connected")),S.connected=new WeakSet,S.length_c=0,S.length_d||t.delete(b),f=!0)}return f}function E(u,i){let f=!1;for(let b of u)i&&d(b).then(E),!(!t.has(b)||!t.get(b).length_d)&&(b.dispatchEvent(new Event("dde:disconnected")),t.delete(b),f=!0);return f}}var p=Symbol.for("Signal");function D(t){try{return Reflect.has(t,p)}catch{return!1}}var T=[],l=new WeakMap;function g(t,e){if(typeof t!="function")return V(t,e);if(D(t))return t;let n=V(),o=function(){let[r,...c]=l.get(o);if(l.set(o,new Set([r])),T.push(o),n(t()),T.pop(),!c.length)return;let s=l.get(o);for(let a of c)s.has(a)||O(a,o)};return l.set(n[p],o),l.set(o,new Set([n])),o(),n}g.action=function(t,e,...n){let o=t[p],{actions:r}=o;if(!r||!Reflect.has(r,e))throw new Error(`'${t}' has no action with name '${e}'!`);if(r[e].apply(o,n),o.skip)return Reflect.deleteProperty(o,"skip");o.listeners.forEach(c=>c(o.value))};g.on=function t(e,n,o={}){let{signal:r}=o;if(!(r&&r.aborted)){if(Array.isArray(e))return e.forEach(c=>t(c,n,o));z(e,n),r&&r.addEventListener("abort",()=>O(e,n))}};g.symbols={signal:p,onclear:Symbol.for("Signal.onclear")};var A="__dde_attributes";g.attribute=function(t,e=void 0){let n=g(e),o;return _.host(r=>{if(o=r,r instanceof HTMLElement?r.hasAttribute(t)&&n(r.getAttribute(t)):r.hasAttributeNS(null,t)&&n(r.getAttributeNS(null,t)),r[A]){r[A][t]=n;return}return r[A]={[t]:n},x.attributeChanged(function({detail:s}){/*! This maps attributes to signals (`S.attribute`). -* Investigate `__dde_attributes` key of the element.*/let[a,d]=s,h=r[A][a];if(h)return h(d)})(r),x.disconnected(function(){/*! This removes all signals mapped to attributes (`S.attribute`). -* Investigate `__dde_attributes` key of the element.*/g.clear(...Object.values(r[A])),o=null})(r),r}),new Proxy(n,{apply(r,c,s){if(!s.length)return r();if(!o)return;let a=s[0];return o instanceof HTMLElement?o.setAttribute(t,a):o.setAttributeNS(null,t,a)}})};g.clear=function(...t){for(let n of t){Reflect.deleteProperty(n,"toJSON");let o=n[p];o.onclear.forEach(r=>r.call(o)),e(n,o),Reflect.deleteProperty(n,p)}function e(n,o){o.listeners.forEach(r=>{if(o.listeners.delete(r),!l.has(r))return;let c=l.get(r);c.delete(n),!(c.size>1)&&(g.clear(...c),l.delete(r))})}};var k="__dde_reactive";g.el=function(t,e){let n=m.mark({type:"reactive"},!1),o=n.end,r=document.createDocumentFragment();r.append(n,o);let{current:c}=_,s=a=>{if(!n.parentNode||!o.parentNode)return O(t,s);_.push(c);let d=e(a);_.pop(),Array.isArray(d)||(d=[d]);let h=n;for(;(h=n.nextSibling)!==o;)h.remove();n.after(...d)};return z(t,s),Q(t,s,n,e),s(t()),r};var K={isSignal:D,processReactiveAttribute(t,e,n,o){if(!D(n))return n;let r=c=>o(e,c);return z(n,r),Q(n,r,t,e),n()}};function Q(t,e,...n){let{current:o}=_;o.prevent||o.host(function(r){r[k]||(r[k]=[],x.disconnected(()=>r[k].forEach(([[c,s]])=>O(c,s,c[p]?.host()===r)))(r)),r[k].push([[t,e],...n])})}function V(t,e){let n=(...o)=>o.length?at(n,...o):ft(n);return it(n,t,e)}var st=Object.assign(Object.create(null),{stopPropagation(){this.skip=!0}}),$=class extends Error{constructor(){super();let[e,...n]=this.stack.split(` -`),o=e.slice(e.indexOf("@"),e.indexOf(".js:")+4);this.stack=n.find(r=>!r.includes(o))}};function it(t,e,n){let o=[];F(n)!=="[object Object]"&&(n={});let{onclear:r}=g.symbols;n[r]&&(o.push(n[r]),Reflect.deleteProperty(n,r));let{host:c}=_;return Reflect.defineProperty(t,p,{value:{value:e,actions:n,onclear:o,host:c,listeners:new Set,defined:new $},enumerable:!1,writable:!1,configurable:!0}),t.toJSON=()=>t(),Object.setPrototypeOf(t[p],st),t}function ut(){return T[T.length-1]}function ft(t){if(!t[p])return;let{value:e,listeners:n}=t[p],o=ut();return o&&n.add(o),l.has(o)&&l.get(o).add(t),e}function at(t,e,n){if(!t[p])return;let o=t[p];if(!(!n&&o.value===e))return o.value=e,o.listeners.forEach(r=>r(e)),e}function z(t,e){if(t[p])return t[p].listeners.add(e)}function O(t,e,n){let o=t[p];if(!o)return;let r=o.listeners.delete(e);if(n&&!o.listeners.size){if(g.clear(t),!l.has(o))return r;let c=l.get(o);if(!l.has(c))return r;l.get(c).forEach(s=>O(s,c,!0))}return r}M(K);export{g as S,N as assign,I as assignAttribute,Y as classListDeclarative,m as createElement,bt as createElementNS,xt as dispatchEvent,m as el,bt as elNS,Et as empty,D as isSignal,x as on,M as registerReactivity,_ as scope}; +var y={isSignal(t){return!1},processReactiveAttribute(t,e,n,r){return n}};function M(t,e=!0){return e?Object.assign(y,t):(Object.setPrototypeOf(t,y),t)}function R(t){return y.isPrototypeOf(t)&&t!==y?t:y}function _(t){return typeof t>"u"}function U(t){let e=typeof t;return e!=="object"?e:t===null?"null":Object.prototype.toString.call(t)}function C(t,e){if(!t||!(t instanceof AbortSignal))return!0;if(!t.aborted)return t.addEventListener("abort",e),function(){t.removeEventListener("abort",e)}}var W={setDeleteAttr:X,ssr:!1};function X(t,e,n){if(Reflect.set(t,e,n),!!_(n)){if(Reflect.deleteProperty(t,e),t instanceof HTMLElement&&t.getAttribute(e)==="undefined")return t.removeAttribute(e);if(Reflect.get(t,e)==="undefined")return Reflect.set(t,e,"")}}var w=[{scope:document.body,host:t=>t?t(document.body):document.body,custom_element:!1,prevent:!0}],g={get current(){return w[w.length-1]},get host(){return this.current.host},preventDefault(){let{current:t}=this;return t.prevent=!0,t},get state(){return[...w]},push(t={}){return w.push(Object.assign({},this.current,{prevent:!1},t))},pop(){return w.pop()}},L;function E(t,e,...n){let r=R(this),o=0,c,s;switch((Object(e)!==e||r.isSignal(e))&&(e={textContent:e}),!0){case typeof t=="function":{o=1,g.push({scope:t,host:p=>p?(o===1?n.unshift(p):p(s),void 0):s}),c=t(e||void 0);let a=c instanceof DocumentFragment;if(c.nodeName==="#comment")break;let d=E.mark({type:"component",name:t.name,host:a?"this":"parentElement"});c.prepend(d),a&&(s=d);break}case t==="#text":c=N.call(this,document.createTextNode(""),e);break;case(t==="<>"||!t):c=N.call(this,document.createDocumentFragment(),e);break;case L:c=N.call(this,document.createElementNS(L,t),e);break;case!c:c=N.call(this,document.createElement(t),e)}return rt(c),s||(s=c),n.forEach(a=>a(s)),o&&g.pop(),o=2,c}E.mark=function(t,e=!1){W.ssr&&(t.ssr=!0),t=Object.entries(t).map(([o,c])=>o+`="${c}"`).join(" ");let n=e?"":"/",r=document.createComment(``);return e||(r.end=document.createComment("")),r};E.later=function(){let t=E.mark({type:"later"});return t.append=t.prepend=function(...e){return t.after(...e),t},t};function mt(t){let e=this;return function(...r){L=t;let o=E.call(e,...r);return L=void 0,o}}var{setDeleteAttr:q}=W,j=new WeakMap;function N(t,...e){if(!e.length)return t;j.set(t,J(t,this));for(let[n,r]of Object.entries(Object.assign({},...e)))I.call(this,t,n,r);return j.delete(t),t}function I(t,e,n){let{setRemoveAttr:r,s:o}=J(t,this),c=this;n=o.processReactiveAttribute(t,e,n,(a,d)=>I.call(c,t,a,d));let[s]=e;if(s==="=")return r(e.slice(1),n);if(s===".")return H(t,e.slice(1),n);if(/(aria|data)([A-Z])/.test(e))return e=e.replace(/([a-z])([A-Z])/g,"$1-$2").toLowerCase(),r(e,n);switch(e==="className"&&(e="class"),e){case"xlink:href":return r(e,n,"http://www.w3.org/1999/xlink");case"textContent":return q(t,e,n);case"style":if(typeof n!="object")break;case"dataset":return $(o,n,H.bind(null,t[e]));case"ariaset":return $(o,n,(a,d)=>r("aria-"+a,d));case"classList":return Y.call(c,t,n)}return tt(t,e)?q(t,e,n):r(e,n)}function J(t,e){if(j.has(t))return j.get(t);let r=(t instanceof SVGElement?nt:et).bind(null,t,"Attribute"),o=R(e);return{setRemoveAttr:r,s:o}}function Y(t,e){let n=R(this);return $(n,e,(r,o)=>t.classList.toggle(r,o===-1?void 0:!!o)),t}function _t(t){return Array.from(t.children).forEach(e=>e.remove()),t}function tt(t,e){if(!Reflect.has(t,e))return!1;let n=Z(t,e);return!_(n.set)}function Z(t,e){if(t=Object.getPrototypeOf(t),!t)return{};let n=Object.getOwnPropertyDescriptor(t,e);return n||Z(t,e)}function $(t,e,n){if(!(typeof e!="object"||e===null))return Object.entries(e).forEach(function([o,c]){o&&(c=t.processReactiveAttribute(e,o,c,n),n(o,c))})}function G(t){return Array.isArray(t)?t.filter(Boolean).join(" "):t}function et(t,e,n,r){return t[(_(r)?"remove":"set")+e](n,G(r))}function nt(t,e,n,r,o=null){return t[(_(r)?"remove":"set")+e+"NS"](o,n,G(r))}function H(t,e,n){if(Reflect.set(t,e,n),!!_(n))return Reflect.deleteProperty(t,e)}function B(...t){return this.appendOrig(...t),this}function rt(t){return t.append===B||(t.appendOrig=t.append,t.append=B),t}function xt(t,e,...n){let r=n.length?new CustomEvent(e,{detail:n[0]}):new Event(e);return t.dispatchEvent(r)}function v(t,e,n){return function(o){return o.addEventListener(t,e,n),o}}var P=ct(),ot=new WeakSet;v.connected=function(t,e){let{custom_element:n}=g.current,r="connected";return typeof e!="object"&&(e={}),e.once=!0,function(c){n&&(c=n);let s="dde:"+r;return c.addEventListener(s,t,e),c.__dde_lifecycleToEvents?c:c.isConnected?(c.dispatchEvent(new Event(s)),c):(C(e.signal,()=>P.offConnected(c,t))&&P.onConnected(c,t),c)}};v.disconnected=function(t,e){let{custom_element:n}=g.current,r="disconnected";return typeof e!="object"&&(e={}),e.once=!0,function(c){n&&(c=n);let s="dde:"+r;return c.addEventListener(s,t,e),c.__dde_lifecycleToEvents||C(e.signal,()=>P.offDisconnected(c,t))&&P.onDisconnected(c,t),c}};v.attributeChanged=function(t,e){let n="attributeChanged";return typeof e!="object"&&(e={}),function(o){let c="dde:"+n;if(o.addEventListener(c,t,e),o.__dde_lifecycleToEvents||ot.has(o))return o;let s=new MutationObserver(function(d){for(let{attributeName:p,target:x}of d)x.dispatchEvent(new CustomEvent(c,{detail:[p,x.getAttribute(p)]}))});return C(e.signal,()=>s.disconnect())&&s.observe(o,{attributes:!0}),o}};function ct(){let t=new Map,e=!1,n=new MutationObserver(function(i){for(let u of i)if(u.type==="childList"){if(p(u.addedNodes,!0)){s();continue}x(u.removedNodes,!0)&&s()}});return{onConnected(i,u){c();let f=o(i);f.connected.has(u)||(f.connected.add(u),f.length_c+=1)},offConnected(i,u){if(!t.has(i))return;let f=t.get(i);f.connected.has(u)&&(f.connected.delete(u),f.length_c-=1,r(i,f))},onDisconnected(i,u){c();let f=o(i);f.disconnected.has(u)||(f.disconnected.add(u),f.length_d+=1)},offDisconnected(i,u){if(!t.has(i))return;let f=t.get(i);f.disconnected.has(u)&&(f.disconnected.delete(u),f.length_d-=1,r(i,f))}};function r(i,u){u.length_c||u.length_d||(t.delete(i),s())}function o(i){if(t.has(i))return t.get(i);let u={connected:new WeakSet,length_c:0,disconnected:new WeakSet,length_d:0};return t.set(i,u),u}function c(){e||(e=!0,n.observe(document.body,{childList:!0,subtree:!0}))}function s(){!e||t.size||(e=!1,n.disconnect())}function a(){return new Promise(function(i){(requestIdleCallback||requestAnimationFrame)(i)})}async function d(i){t.size>30&&await a();let u=[];if(!(i instanceof Node))return u;for(let f of t.keys())f===i||!(f instanceof Node)||i.contains(f)&&u.push(f);return u}function p(i,u){let f=!1;for(let m of i){if(u&&d(m).then(p),!t.has(m))continue;let S=t.get(m);S.length_c&&(m.dispatchEvent(new Event("dde:connected")),S.connected=new WeakSet,S.length_c=0,S.length_d||t.delete(m),f=!0)}return f}function x(i,u){let f=!1;for(let m of i)u&&d(m).then(x),!(!t.has(m)||!t.get(m).length_d)&&(m.dispatchEvent(new Event("dde:disconnected")),t.delete(m),f=!0);return f}}var l=Symbol.for("Signal");function D(t){try{return Reflect.has(t,l)}catch{return!1}}var T=[],h=new WeakMap;function b(t,e){if(typeof t!="function")return V(t,e);if(D(t))return t;let n=V(),r=function(){let[o,...c]=h.get(r);if(h.set(r,new Set([o])),T.push(r),n(t()),T.pop(),!c.length)return;let s=h.get(r);for(let a of c)s.has(a)||O(a,r)};return h.set(n[l],r),h.set(r,new Set([n])),r(),n}b.action=function(t,e,...n){let r=t[l],{actions:o}=r;if(!o||!Reflect.has(o,e))throw new Error(`'${t}' has no action with name '${e}'!`);if(o[e].apply(r,n),r.skip)return Reflect.deleteProperty(r,"skip");r.listeners.forEach(c=>c(r.value))};b.on=function t(e,n,r={}){let{signal:o}=r;if(!(o&&o.aborted)){if(Array.isArray(e))return e.forEach(c=>t(c,n,r));F(e,n),o&&o.addEventListener("abort",()=>O(e,n))}};b.symbols={signal:l,onclear:Symbol.for("Signal.onclear")};var A="__dde_attributes";b.attribute=function(t,e=void 0){let n=b(e),r;return g.host(o=>{if(r=o,o instanceof HTMLElement?o.hasAttribute(t)&&n(o.getAttribute(t)):o.hasAttributeNS(null,t)&&n(o.getAttributeNS(null,t)),o[A]){o[A][t]=n;return}return o[A]={[t]:n},v.attributeChanged(function({detail:s}){/*! This maps attributes to signals (`S.attribute`). +* Investigate `__dde_attributes` key of the element.*/let[a,d]=s,p=o[A][a];if(p)return p(d)})(o),v.disconnected(function(){/*! This removes all signals mapped to attributes (`S.attribute`). +* Investigate `__dde_attributes` key of the element.*/b.clear(...Object.values(o[A])),r=null})(o),o}),new Proxy(n,{apply(o,c,s){if(!s.length)return o();if(!r)return;let a=s[0];return r instanceof HTMLElement?r.setAttribute(t,a):r.setAttributeNS(null,t,a)}})};b.clear=function(...t){for(let n of t){Reflect.deleteProperty(n,"toJSON");let r=n[l];r.onclear.forEach(o=>o.call(r)),e(n,r),Reflect.deleteProperty(n,l)}function e(n,r){r.listeners.forEach(o=>{if(r.listeners.delete(o),!h.has(o))return;let c=h.get(o);c.delete(n),!(c.size>1)&&(b.clear(...c),h.delete(o))})}};var k="__dde_reactive";b.el=function(t,e){let n=E.mark({type:"reactive"},!1),r=n.end,o=document.createDocumentFragment();o.append(n,r);let{current:c}=g,s=a=>{if(!n.parentNode||!r.parentNode)return O(t,s);g.push(c);let d=e(a);g.pop(),Array.isArray(d)||(d=[d]);let p=n;for(;(p=n.nextSibling)!==r;)p.remove();n.after(...d)};return F(t,s),Q(t,s,n,e),s(t()),o};var K={isSignal:D,processReactiveAttribute(t,e,n,r){if(!D(n))return n;let o=c=>r(e,c);return F(n,o),Q(n,o,t,e),n()}};function Q(t,e,...n){let{current:r}=g;r.prevent||r.host(function(o){o[k]||(o[k]=[],v.disconnected(()=>o[k].forEach(([[c,s]])=>O(c,s,c[l]?.host()===o)))(o)),o[k].push([[t,e],...n])})}function V(t,e){let n=(...r)=>r.length?at(n,...r):ft(n);return it(n,t,e)}var st=Object.assign(Object.create(null),{stopPropagation(){this.skip=!0}}),z=class extends Error{constructor(){super();let[e,...n]=this.stack.split(` +`),r=e.slice(e.indexOf("@"),e.indexOf(".js:")+4);this.stack=n.find(o=>!o.includes(r))}};function it(t,e,n){let r=[];U(n)!=="[object Object]"&&(n={});let{onclear:o}=b.symbols;n[o]&&(r.push(n[o]),Reflect.deleteProperty(n,o));let{host:c}=g;return Reflect.defineProperty(t,l,{value:{value:e,actions:n,onclear:r,host:c,listeners:new Set,defined:new z},enumerable:!1,writable:!1,configurable:!0}),t.toJSON=()=>t(),Object.setPrototypeOf(t[l],st),t}function ut(){return T[T.length-1]}function ft(t){if(!t[l])return;let{value:e,listeners:n}=t[l],r=ut();return r&&n.add(r),h.has(r)&&h.get(r).add(t),e}function at(t,e,n){if(!t[l])return;let r=t[l];if(!(!n&&r.value===e))return r.value=e,r.listeners.forEach(o=>o(e)),e}function F(t,e){if(t[l])return t[l].listeners.add(e)}function O(t,e,n){let r=t[l];if(!r)return;let o=r.listeners.delete(e);if(n&&!r.listeners.size){if(b.clear(t),!h.has(r))return o;let c=h.get(r);if(!h.has(c))return o;h.get(c).forEach(s=>O(s,c,!0))}return o}M(K);export{b as S,N as assign,I as assignAttribute,Y as classListDeclarative,E as createElement,mt as createElementNS,xt as dispatchEvent,E as el,mt as elNS,_t as empty,D as isSignal,v as on,M as registerReactivity,g as scope}; diff --git a/dist/esm.d.ts b/dist/esm.d.ts index db4d037..aea9e06 100644 --- a/dist/esm.d.ts +++ b/dist/esm.d.ts @@ -121,7 +121,7 @@ interface On{ ) : EE; } export const on: On; -type Scope= { scope: Node | Function | Object, host: ddeElementModifier, prevent: boolean, inherit_host: boolean, } +type Scope= { scope: Node | Function | Object, host: ddeElementModifier, custom_element: false | HTMLElement, prevent: boolean } /** Current scope created last time the `el(Function)` was invoke. (Or {@link scope.push}) */ export const scope: { current: Scope, @@ -431,4 +431,8 @@ declare global{ /** Elements returned by {@link el} return parent element for `.append` method. **Regullarly created elements are untouched.** */ append: ddeAppend; } + interface SVGElement{ + /** Elements returned by {@link el} return parent element for `.append` method. **Regullarly created elements are untouched.** */ + append: ddeAppend; + } } \ No newline at end of file diff --git a/dist/esm.js b/dist/esm.js index 1dc5237..adbf83e 100644 --- a/dist/esm.js +++ b/dist/esm.js @@ -1 +1 @@ -var m={isSignal(t){return!1},processReactiveAttribute(t,e,n,o){return n}};function $(t,e=!0){return e?Object.assign(m,t):(Object.setPrototypeOf(t,m),t)}function _(t){return m.isPrototypeOf(t)&&t!==m?t:m}function g(t){return typeof t>"u"}function x(t,e){if(!t||!(t instanceof AbortSignal))return!0;if(!t.aborted)return t.addEventListener("abort",e),function(){t.removeEventListener("abort",e)}}var L={setDeleteAttr:U};function U(t,e,n){if(Reflect.set(t,e,n),!!g(n)){if(Reflect.deleteProperty(t,e),t instanceof HTMLElement&&t.getAttribute(e)==="undefined")return t.removeAttribute(e);if(Reflect.get(t,e)==="undefined")return Reflect.set(t,e,"")}}var v=[{scope:document.body,host:t=>t?t(document.body):document.body,prevent:!0,inherit_host:!1}],S={get current(){return v[v.length-1]},get host(){return this.current.host},preventDefault(){let{current:t}=this;return t.prevent=!0,t},get state(){return[...v]},push(t={}){return v.push(Object.assign({},this.current,{prevent:!1},t))},pop(){return v.pop()}},A;function E(t,e,...n){let o=_(this),r=0,s,f;switch((Object(e)!==e||o.isSignal(e))&&(e={textContent:e}),!0){case typeof t=="function":{r=1;let{inherit_host:d,host:p}=S.current,l=d?p:c=>c?(r===1?n.unshift(c):c(f),void 0):f;S.push({scope:t,host:l,inherit_host:d}),s=t(e||void 0);let h=s instanceof DocumentFragment,i=E.mark({type:"component",name:t.name,host:h?"this":s.nodeName==="#comment"?"previousLater":"parentElement"});s.prepend(i),h&&(f=i);break}case t==="#text":s=w.call(this,document.createTextNode(""),e);break;case(t==="<>"||!t):s=w.call(this,document.createDocumentFragment(),e);break;case A:s=w.call(this,document.createElementNS(A,t),e);break;case!s:s=w.call(this,document.createElement(t),e)}return B(s),f||(f=s),n.forEach(d=>d(f)),r&&S.pop(),r=2,s}E.mark=function(t,e=!1){t=Object.entries(t).map(([r,s])=>r+`="${s}"`).join(" ");let n=e?"":"/",o=document.createComment(``);return e||(o.end=document.createComment("")),o};E.later=function(){let t=E.mark({type:"later"});return t.append=t.prepend=function(...e){return t.after(...e),t},t};function Q(t){let e=this;return function(...o){A=t;let r=E.call(e,...o);return A=void 0,r}}var{setDeleteAttr:N}=L,O=new WeakMap;function w(t,...e){if(!e.length)return t;O.set(t,T(t,this));for(let[n,o]of Object.entries(Object.assign({},...e)))P.call(this,t,n,o);return O.delete(t),t}function P(t,e,n){let{setRemoveAttr:o,s:r}=T(t,this),s=this;n=r.processReactiveAttribute(t,e,n,(d,p)=>P.call(s,t,d,p));let[f]=e;if(f==="=")return o(e.slice(1),n);if(f===".")return D(t,e.slice(1),n);if(/(aria|data)([A-Z])/.test(e))return e=e.replace(/([a-z])([A-Z])/g,"$1-$2").toLowerCase(),o(e,n);switch(e==="className"&&(e="class"),e){case"xlink:href":return o(e,n,"http://www.w3.org/1999/xlink");case"textContent":return N(t,e,n);case"style":if(typeof n!="object")break;case"dataset":return R(r,n,D.bind(null,t[e]));case"ariaset":return R(r,n,(d,p)=>o("aria-"+d,p));case"classList":return q.call(s,t,n)}return z(t,e)?N(t,e,n):o(e,n)}function T(t,e){if(O.has(t))return O.get(t);let o=(t instanceof SVGElement?k:F).bind(null,t,"Attribute"),r=_(e);return{setRemoveAttr:o,s:r}}function q(t,e){let n=_(this);return R(n,e,(o,r)=>t.classList.toggle(o,r===-1?void 0:!!r)),t}function Y(t){return Array.from(t.children).forEach(e=>e.remove()),t}function z(t,e){if(!Reflect.has(t,e))return!1;let n=W(t,e);return!g(n.set)}function W(t,e){if(t=Object.getPrototypeOf(t),!t)return{};let n=Object.getOwnPropertyDescriptor(t,e);return n||W(t,e)}function R(t,e,n){if(!(typeof e!="object"||e===null))return Object.entries(e).forEach(function([r,s]){r&&(s=t.processReactiveAttribute(e,r,s,n),n(r,s))})}function M(t){return Array.isArray(t)?t.filter(Boolean).join(" "):t}function F(t,e,n,o){return t[(g(o)?"remove":"set")+e](n,M(o))}function k(t,e,n,o,r=null){return t[(g(o)?"remove":"set")+e+"NS"](r,n,M(o))}function D(t,e,n){if(Reflect.set(t,e,n),!!g(n))return Reflect.deleteProperty(t,e)}function j(...t){return this.appendOrig(...t),this}function B(t){return t.append===j||(t.appendOrig=t.append,t.append=j),t}function nt(t,e,...n){let o=n.length?new CustomEvent(e,{detail:n[0]}):new Event(e);return t.dispatchEvent(o)}function y(t,e,n){return function(r){return r.addEventListener(t,e,n),r}}var C=Z(),I=new WeakSet;y.connected=function(t,e){let n="connected";return typeof e!="object"&&(e={}),e.once=!0,function(r){let s="dde:"+n;return r.addEventListener(s,t,e),r.__dde_lifecycleToEvents?r:r.isConnected?(r.dispatchEvent(new Event(s)),r):(x(e.signal,()=>C.offConnected(r,t))&&C.onConnected(r,t),r)}};y.disconnected=function(t,e){let n="disconnected";return typeof e!="object"&&(e={}),e.once=!0,function(r){let s="dde:"+n;return r.addEventListener(s,t,e),r.__dde_lifecycleToEvents||x(e.signal,()=>C.offDisconnected(r,t))&&C.onDisconnected(r,t),r}};y.attributeChanged=function(t,e){let n="attributeChanged";return typeof e!="object"&&(e={}),function(r){let s="dde:"+n;if(r.addEventListener(s,t,e),r.__dde_lifecycleToEvents||I.has(r))return r;let f=new MutationObserver(function(p){for(let{attributeName:l,target:h}of p)h.dispatchEvent(new CustomEvent(s,{detail:[l,h.getAttribute(l)]}))});return x(e.signal,()=>f.disconnect())&&f.observe(r,{attributes:!0}),r}};function Z(){let t=new Map,e=!1,n=new MutationObserver(function(i){for(let c of i)if(c.type==="childList"){if(l(c.addedNodes,!0)){f();continue}h(c.removedNodes,!0)&&f()}});return{onConnected(i,c){s();let u=r(i);u.connected.has(c)||(u.connected.add(c),u.length_c+=1)},offConnected(i,c){if(!t.has(i))return;let u=t.get(i);u.connected.has(c)&&(u.connected.delete(c),u.length_c-=1,o(i,u))},onDisconnected(i,c){s();let u=r(i);u.disconnected.has(c)||(u.disconnected.add(c),u.length_d+=1)},offDisconnected(i,c){if(!t.has(i))return;let u=t.get(i);u.disconnected.has(c)&&(u.disconnected.delete(c),u.length_d-=1,o(i,u))}};function o(i,c){c.length_c||c.length_d||(t.delete(i),f())}function r(i){if(t.has(i))return t.get(i);let c={connected:new WeakSet,length_c:0,disconnected:new WeakSet,length_d:0};return t.set(i,c),c}function s(){e||(e=!0,n.observe(document.body,{childList:!0,subtree:!0}))}function f(){!e||t.size||(e=!1,n.disconnect())}function d(){return new Promise(function(i){(requestIdleCallback||requestAnimationFrame)(i)})}async function p(i){t.size>30&&await d();let c=[];if(!(i instanceof Node))return c;for(let u of t.keys())u===i||!(u instanceof Node)||i.contains(u)&&c.push(u);return c}function l(i,c){let u=!1;for(let a of i){if(c&&p(a).then(l),!t.has(a))continue;let b=t.get(a);b.length_c&&(a.dispatchEvent(new Event("dde:connected")),b.connected=new WeakSet,b.length_c=0,b.length_d||t.delete(a),u=!0)}return u}function h(i,c){let u=!1;for(let a of i)c&&p(a).then(h),!(!t.has(a)||!t.get(a).length_d)&&(a.dispatchEvent(new Event("dde:disconnected")),t.delete(a),u=!0);return u}}export{w as assign,P as assignAttribute,q as classListDeclarative,E as createElement,Q as createElementNS,nt as dispatchEvent,E as el,Q as elNS,Y as empty,y as on,$ as registerReactivity,S as scope}; +var b={isSignal(t){return!1},processReactiveAttribute(t,e,n,c){return n}};function $(t,e=!0){return e?Object.assign(b,t):(Object.setPrototypeOf(t,b),t)}function x(t){return b.isPrototypeOf(t)&&t!==b?t:b}function l(t){return typeof t>"u"}function w(t,e){if(!t||!(t instanceof AbortSignal))return!0;if(!t.aborted)return t.addEventListener("abort",e),function(){t.removeEventListener("abort",e)}}var R={setDeleteAttr:U,ssr:!1};function U(t,e,n){if(Reflect.set(t,e,n),!!l(n)){if(Reflect.deleteProperty(t,e),t instanceof HTMLElement&&t.getAttribute(e)==="undefined")return t.removeAttribute(e);if(Reflect.get(t,e)==="undefined")return Reflect.set(t,e,"")}}var v=[{scope:document.body,host:t=>t?t(document.body):document.body,custom_element:!1,prevent:!0}],E={get current(){return v[v.length-1]},get host(){return this.current.host},preventDefault(){let{current:t}=this;return t.prevent=!0,t},get state(){return[...v]},push(t={}){return v.push(Object.assign({},this.current,{prevent:!1},t))},pop(){return v.pop()}},O;function _(t,e,...n){let c=x(this),o=0,r,f;switch((Object(e)!==e||c.isSignal(e))&&(e={textContent:e}),!0){case typeof t=="function":{o=1,E.push({scope:t,host:h=>h?(o===1?n.unshift(h):h(f),void 0):f}),r=t(e||void 0);let d=r instanceof DocumentFragment;if(r.nodeName==="#comment")break;let a=_.mark({type:"component",name:t.name,host:d?"this":"parentElement"});r.prepend(a),d&&(f=a);break}case t==="#text":r=A.call(this,document.createTextNode(""),e);break;case(t==="<>"||!t):r=A.call(this,document.createDocumentFragment(),e);break;case O:r=A.call(this,document.createElementNS(O,t),e);break;case!r:r=A.call(this,document.createElement(t),e)}return B(r),f||(f=r),n.forEach(d=>d(f)),o&&E.pop(),o=2,r}_.mark=function(t,e=!1){R.ssr&&(t.ssr=!0),t=Object.entries(t).map(([o,r])=>o+`="${r}"`).join(" ");let n=e?"":"/",c=document.createComment(``);return e||(c.end=document.createComment("")),c};_.later=function(){let t=_.mark({type:"later"});return t.append=t.prepend=function(...e){return t.after(...e),t},t};function X(t){let e=this;return function(...c){O=t;let o=_.call(e,...c);return O=void 0,o}}var{setDeleteAttr:D}=R,C=new WeakMap;function A(t,...e){if(!e.length)return t;C.set(t,T(t,this));for(let[n,c]of Object.entries(Object.assign({},...e)))P.call(this,t,n,c);return C.delete(t),t}function P(t,e,n){let{setRemoveAttr:c,s:o}=T(t,this),r=this;n=o.processReactiveAttribute(t,e,n,(d,a)=>P.call(r,t,d,a));let[f]=e;if(f==="=")return c(e.slice(1),n);if(f===".")return L(t,e.slice(1),n);if(/(aria|data)([A-Z])/.test(e))return e=e.replace(/([a-z])([A-Z])/g,"$1-$2").toLowerCase(),c(e,n);switch(e==="className"&&(e="class"),e){case"xlink:href":return c(e,n,"http://www.w3.org/1999/xlink");case"textContent":return D(t,e,n);case"style":if(typeof n!="object")break;case"dataset":return y(o,n,L.bind(null,t[e]));case"ariaset":return y(o,n,(d,a)=>c("aria-"+d,a));case"classList":return k.call(r,t,n)}return q(t,e)?D(t,e,n):c(e,n)}function T(t,e){if(C.has(t))return C.get(t);let c=(t instanceof SVGElement?F:z).bind(null,t,"Attribute"),o=x(e);return{setRemoveAttr:c,s:o}}function k(t,e){let n=x(this);return y(n,e,(c,o)=>t.classList.toggle(c,o===-1?void 0:!!o)),t}function Y(t){return Array.from(t.children).forEach(e=>e.remove()),t}function q(t,e){if(!Reflect.has(t,e))return!1;let n=W(t,e);return!l(n.set)}function W(t,e){if(t=Object.getPrototypeOf(t),!t)return{};let n=Object.getOwnPropertyDescriptor(t,e);return n||W(t,e)}function y(t,e,n){if(!(typeof e!="object"||e===null))return Object.entries(e).forEach(function([o,r]){o&&(r=t.processReactiveAttribute(e,o,r,n),n(o,r))})}function M(t){return Array.isArray(t)?t.filter(Boolean).join(" "):t}function z(t,e,n,c){return t[(l(c)?"remove":"set")+e](n,M(c))}function F(t,e,n,c,o=null){return t[(l(c)?"remove":"set")+e+"NS"](o,n,M(c))}function L(t,e,n){if(Reflect.set(t,e,n),!!l(n))return Reflect.deleteProperty(t,e)}function j(...t){return this.appendOrig(...t),this}function B(t){return t.append===j||(t.appendOrig=t.append,t.append=j),t}function nt(t,e,...n){let c=n.length?new CustomEvent(e,{detail:n[0]}):new Event(e);return t.dispatchEvent(c)}function N(t,e,n){return function(o){return o.addEventListener(t,e,n),o}}var S=Z(),I=new WeakSet;N.connected=function(t,e){let{custom_element:n}=E.current,c="connected";return typeof e!="object"&&(e={}),e.once=!0,function(r){n&&(r=n);let f="dde:"+c;return r.addEventListener(f,t,e),r.__dde_lifecycleToEvents?r:r.isConnected?(r.dispatchEvent(new Event(f)),r):(w(e.signal,()=>S.offConnected(r,t))&&S.onConnected(r,t),r)}};N.disconnected=function(t,e){let{custom_element:n}=E.current,c="disconnected";return typeof e!="object"&&(e={}),e.once=!0,function(r){n&&(r=n);let f="dde:"+c;return r.addEventListener(f,t,e),r.__dde_lifecycleToEvents||w(e.signal,()=>S.offDisconnected(r,t))&&S.onDisconnected(r,t),r}};N.attributeChanged=function(t,e){let n="attributeChanged";return typeof e!="object"&&(e={}),function(o){let r="dde:"+n;if(o.addEventListener(r,t,e),o.__dde_lifecycleToEvents||I.has(o))return o;let f=new MutationObserver(function(a){for(let{attributeName:h,target:g}of a)g.dispatchEvent(new CustomEvent(r,{detail:[h,g.getAttribute(h)]}))});return w(e.signal,()=>f.disconnect())&&f.observe(o,{attributes:!0}),o}};function Z(){let t=new Map,e=!1,n=new MutationObserver(function(s){for(let i of s)if(i.type==="childList"){if(h(i.addedNodes,!0)){f();continue}g(i.removedNodes,!0)&&f()}});return{onConnected(s,i){r();let u=o(s);u.connected.has(i)||(u.connected.add(i),u.length_c+=1)},offConnected(s,i){if(!t.has(s))return;let u=t.get(s);u.connected.has(i)&&(u.connected.delete(i),u.length_c-=1,c(s,u))},onDisconnected(s,i){r();let u=o(s);u.disconnected.has(i)||(u.disconnected.add(i),u.length_d+=1)},offDisconnected(s,i){if(!t.has(s))return;let u=t.get(s);u.disconnected.has(i)&&(u.disconnected.delete(i),u.length_d-=1,c(s,u))}};function c(s,i){i.length_c||i.length_d||(t.delete(s),f())}function o(s){if(t.has(s))return t.get(s);let i={connected:new WeakSet,length_c:0,disconnected:new WeakSet,length_d:0};return t.set(s,i),i}function r(){e||(e=!0,n.observe(document.body,{childList:!0,subtree:!0}))}function f(){!e||t.size||(e=!1,n.disconnect())}function d(){return new Promise(function(s){(requestIdleCallback||requestAnimationFrame)(s)})}async function a(s){t.size>30&&await d();let i=[];if(!(s instanceof Node))return i;for(let u of t.keys())u===s||!(u instanceof Node)||s.contains(u)&&i.push(u);return i}function h(s,i){let u=!1;for(let p of s){if(i&&a(p).then(h),!t.has(p))continue;let m=t.get(p);m.length_c&&(p.dispatchEvent(new Event("dde:connected")),m.connected=new WeakSet,m.length_c=0,m.length_d||t.delete(p),u=!0)}return u}function g(s,i){let u=!1;for(let p of s)i&&a(p).then(g),!(!t.has(p)||!t.get(p).length_d)&&(p.dispatchEvent(new Event("dde:disconnected")),t.delete(p),u=!0);return u}}export{A as assign,P as assignAttribute,k as classListDeclarative,_ as createElement,X as createElementNS,nt as dispatchEvent,_ as el,X as elNS,Y as empty,N as on,$ as registerReactivity,E as scope}; diff --git a/docs/code.js.js b/docs/code.js.js new file mode 100644 index 0000000..247a5d1 --- /dev/null +++ b/docs/code.js.js @@ -0,0 +1,12 @@ +const highlighter= await shiki.getHighlighter({ + theme: "css-variables", + langs: ["js", "ts", "css", "html", "shell"], +}); +const codeBlocks= document.querySelectorAll('code[class*="language-"]'); + +codeBlocks.forEach((block)=> { + const lang= block.className.replace("language-", ""); + block.parentElement.dataset.js= "done"; + const html= highlighter.codeToHtml(block.textContent, { lang }); + block.innerHTML= html; +}); diff --git a/docs/elements.html b/docs/elements.html index 9f6c143..99664f3 100644 --- a/docs/elements.html +++ b/docs/elements.html @@ -1,4 +1,4 @@ -`deka-dom-el` — Elements

`deka-dom-el` — Elements

Basic concepts of elements modifications and creations.

Native JavaScript DOM elements creations

Let’s go through all patterns we would like to use and what needs to be improved for better experience.

Creating element(s) (with custom attributes)

You can create a native DOM element by using the document.createElement(). It is also possible to provide a some attribute(s) declaratively using Object.assign(). More precisely, this way you can sets some IDL.

document.body.append(
+`deka-dom-el` — Elements

`deka-dom-el` — Elements

Basic concepts of elements modifications and creations.

Native JavaScript DOM elements creations

Let’s go through all patterns we would like to use and what needs to be improved for better experience.

Creating element(s) (with custom attributes)

You can create a native DOM element by using the document.createElement(). It is also possible to provide a some attribute(s) declaratively using Object.assign(). More precisely, this way you can sets some IDL.

document.body.append( document.createElement("div") ); console.log( @@ -12,7 +12,7 @@ document.body.append( { textContent: "Element’s text content.", style: "color: coral;" } ) ); -

To make this easier, you can use the el function. Internally in basic examples, it is wrapper around assign(document.createElement(…), { … }).

import { el, assign } from "https://cdn.jsdelivr.net/gh/jaandrle/deka-dom-el/dist/esm-with-signals.js";
+

To make this easier, you can use the el function. Internally in basic examples, it is wrapper around assign(document.createElement(…), { … }).

import { el, assign } from "https://cdn.jsdelivr.net/gh/jaandrle/deka-dom-el/dist/esm-with-signals.js"; const color= "lightcoral"; document.body.append( el("p", { textContent: "Hello (first time)", style: { color } }) @@ -23,7 +23,7 @@ document.body.append( { textContent: "Hello (second time)", style: { color } } ) ); -

The assign function provides improved behaviour of Object.assign(). You can declaratively sets any IDL and attribute of the given element. Function prefers IDL and fallback to the element.setAttribute if there is no writable property in the element prototype.

You can study all JavaScript elements interfaces to the corresponding HTML elements. All HTML elements inherits from HTMLElement. To see all available IDLs for example for paragraphs, see HTMLParagraphElement. Moreover, the assign provides a way to sets declaratively some convenient properties:

  • It is possible to sets data-*/aria-* attributes using object notation.
  • In opposite, it is also possible to sets data-*/aria-* attribute using camelCase notation.
  • You can use string or object as a value for style property.
  • className (IDL – preffered)/class are ways to add CSS class to the element. You can use string (similarly to class="…" syntax in HTML) or array of strings. This is handy to concat conditional classes.
  • Use classList to toggle specific classes. This will be handy later when the reactivity via signals is beeing introduced.
  • The assign also accepts the undefined as a value for any property to remove it from the element declaratively. Also for some IDL the corresponding attribute is removed as it can be confusing. For example, natievly the element’s id is removed by setting the IDL to an empty string.

For processing, the assign internally uses assignAttribute and classListDeclarative.

import { assignAttribute, classListDeclarative } from "https://cdn.jsdelivr.net/gh/jaandrle/deka-dom-el/dist/esm-with-signals.js";
+

The assign function provides improved behaviour of Object.assign(). You can declaratively sets any IDL and attribute of the given element. Function prefers IDL and fallback to the element.setAttribute if there is no writable property in the element prototype.

You can study all JavaScript elements interfaces to the corresponding HTML elements. All HTML elements inherits from HTMLElement. To see all available IDLs for example for paragraphs, see HTMLParagraphElement. Moreover, the assign provides a way to sets declaratively some convenient properties:

  • It is possible to sets data-*/aria-* attributes using object notation.
  • In opposite, it is also possible to sets data-*/aria-* attribute using camelCase notation.
  • You can use string or object as a value for style property.
  • className (IDL – preffered)/class are ways to add CSS class to the element. You can use string (similarly to class="…" syntax in HTML) or array of strings. This is handy to concat conditional classes.
  • Use classList to toggle specific classes. This will be handy later when the reactivity via signals is beeing introduced.
  • The assign also accepts the undefined as a value for any property to remove it from the element declaratively. Also for some IDL the corresponding attribute is removed as it can be confusing. For example, natievly the element’s id is removed by setting the IDL to an empty string.

For processing, the assign internally uses assignAttribute and classListDeclarative.

import { assignAttribute, classListDeclarative } from "https://cdn.jsdelivr.net/gh/jaandrle/deka-dom-el/dist/esm-with-signals.js"; const paragraph= document.createElement("p"); assignAttribute(paragraph, "textContent", "Hello, world!"); @@ -48,7 +48,7 @@ console.log(paragraph.outerHTML); document.body.append( paragraph ); -

Native JavaScript templating

By default, the native JS has no good way to define HTML template using DOM API:

document.body.append(
+

Native JavaScript templating

By default, the native JS has no good way to define HTML template using DOM API:

document.body.append( document.createElement("div"), document.createElement("span"), document.createElement("main") @@ -59,7 +59,7 @@ const template= document.createElement("main").append( document.createElement("span"), ); console.log(typeof template==="undefined"); -

This library therefore overwrites the append method of created elements to always return parent element.

import { el } from "https://cdn.jsdelivr.net/gh/jaandrle/deka-dom-el/dist/esm-with-signals.js";
+

This library therefore overwrites the append method of created elements to always return parent element.

import { el } from "https://cdn.jsdelivr.net/gh/jaandrle/deka-dom-el/dist/esm-with-signals.js"; document.head.append( el("style").append( "tr, td{ border: 1px solid red; padding: 1em; }", @@ -83,7 +83,7 @@ document.body.append( ) ) ); -

Creating advanced (reactive) templates and components

Basic components

You can use functions for encapsulation (repeating) logic. The el accepts function as first argument. In that case, the function should return dom elements and the second argument for el is argument for given element.

import { el } from "https://cdn.jsdelivr.net/gh/jaandrle/deka-dom-el/dist/esm-with-signals.js";
+

Basic (state-less) components

You can use functions for encapsulation (repeating) logic. The el accepts function as first argument. In that case, the function should return dom elements and the second argument for el is argument for given element.

import { el } from "https://cdn.jsdelivr.net/gh/jaandrle/deka-dom-el/dist/esm-with-signals.js"; document.head.append( el("style").append( ".class1{ font-weight: bold; }", @@ -100,4 +100,4 @@ function component({ className, textContent }){ el("p", textContent) ); } -

It is nice to use similar naming convention as native DOM API.

\ No newline at end of file +

It is nice to use similar naming convention as native DOM API.

Creating non-HTML elements

\ No newline at end of file diff --git a/docs/index.css b/docs/global.css similarity index 60% rename from docs/index.css rename to docs/global.css index 2ebc7e0..cf88628 100644 --- a/docs/index.css +++ b/docs/global.css @@ -38,21 +38,21 @@ body > nav{ flex-flow: column nowrap; } body > nav { - font-size:1rem; - line-height:2; - padding:1rem 0 0 0 + font-size: 1rem; + line-height: 2; + padding: 1rem 0 0 0; } body > nav ol, body > nav ul { - align-content:space-around; - align-items:center; - display:flex; - flex-direction:row; - flex-wrap:wrap; - justify-content:center; - list-style-type:none; - margin:0; - padding:0 + align-content: space-around; + align-items: center; + display: flex; + flex-direction: row; + flex-wrap: wrap; + justify-content: center; + list-style-type: none; + margin: 0; + padding: 0; } body > nav ol li, body > nav ul li { @@ -96,10 +96,13 @@ body > nav a:hover{ main{ grid-area: content; display: grid; - grid-template-columns: 1fr min(var(--body-max-width), 90%) 1fr; + grid-template-columns: + [full-main-start] 1fr + [main-start] min(var(--body-max-width), 90%) [main-end] + 1fr [full-main-end]; } main > *{ - grid-column: 2; + grid-column: main; } .icon { vertical-align: sub; @@ -116,10 +119,49 @@ main > *{ font-size: .9rem; font-style: italic; } +.code{ + --shiki-color-text: #e9eded; + --shiki-color-background: #212121; + --shiki-token-constant: #82b1ff; + --shiki-token-string: #c3e88d; + --shiki-token-comment: #546e7a; + --shiki-token-keyword: #c792ea; + --shiki-token-parameter: #AA0000; + --shiki-token-function: #80cbae; + --shiki-token-string-expression: #c3e88d; + --shiki-token-punctuation: var(--code); + --shiki-token-link: #EE0000; + white-space: pre; +} +.code[data-js=todo]{ + border: 1px solid var(--border); + border-radius: var(--standard-border-radius); + margin-bottom: 1rem; + + margin-top: 18.4px; + padding: 1rem 1.4rem; +} .example{ - grid-column: 1/-1; + grid-column: full-main; width: 100%; max-width: calc(9/5 * var(--body-max-width)); height: calc(3/5 * var(--body-max-width)); margin-inline: auto; +} +.CodeMirror, .CodeMirror-gutters { + background: #212121 !important; + border: 1px solid white; +} +.prevNext{ + display: grid; + grid-template-columns: 1fr 2fr 1fr; + margin-top: 1rem; + border-top: 1px solid var(--border); +} +.prevNext [rel=prev]{ + grid-column: 1; +} +.prevNext [rel=next]{ + grid-column: 3; + text-align: right; } \ No newline at end of file diff --git a/docs/index.html b/docs/index.html index a6b813e..b8bd953 100644 --- a/docs/index.html +++ b/docs/index.html @@ -1,4 +1,4 @@ -`deka-dom-el` — Introduction

`deka-dom-el` — Introduction

Introducing a library and motivations.

The library tries to provide pure JavaScript tool(s) to create reactive interfaces.

import { el, S } from "https://cdn.jsdelivr.net/gh/jaandrle/deka-dom-el/dist/esm-with-signals.js";
+`deka-dom-el` — Introduction

`deka-dom-el` — Introduction

Introducing a library and motivations.

The library tries to provide pure JavaScript tool(s) to create reactive interfaces.

import { el, S } from "https://cdn.jsdelivr.net/gh/jaandrle/deka-dom-el/dist/esm-with-signals.js"; const clicks= S(0); document.body.append( el().append( @@ -12,4 +12,4 @@ document.body.append( }) ) ); -
\ No newline at end of file + \ No newline at end of file diff --git a/docs_src/components/code.html.js b/docs_src/components/code.html.js new file mode 100644 index 0000000..bf0ee80 --- /dev/null +++ b/docs_src/components/code.html.js @@ -0,0 +1,59 @@ +import { registerClientFile, styles } from "../ssr.js"; +styles.scope(code).css` +:host{ + --shiki-color-text: #e9eded; + --shiki-color-background: #212121; + --shiki-token-constant: #82b1ff; + --shiki-token-string: #c3e88d; + --shiki-token-comment: #546e7a; + --shiki-token-keyword: #c792ea; + --shiki-token-parameter: #AA0000; + --shiki-token-function: #80cbae; + --shiki-token-string-expression: #c3e88d; + --shiki-token-punctuation: var(--code); + --shiki-token-link: #EE0000; + white-space: pre; +} +:host[data-js=todo]{ + border: 1px solid var(--border); + border-radius: var(--standard-border-radius); + margin-bottom: 1rem; + ${/* to fix shift when → dataJS=done */""} + margin-top: 18.4px; + padding: 1rem 1.4rem; +} +`; +import { el } from "deka-dom-el"; +/** + * Prints code to the page and registers flems to make it interactive. + * @param {object} attrs + * @param {string} [attrs.id] + * @param {string} [attrs.className] + * @param {string} attrs.content Example code file path + * @param {"js"|"ts"|"html"|"css"} [attrs.language="js"] Language of the code + * @param {string} [attrs.page_id] ID of the page, if setted it registers shiki + * */ +export function code({ id, content, language= "js", className= "code", page_id }){ + let dataJS; + if(page_id){ + registerClientPart(page_id); + dataJS= "todo"; + } + return el("div", { id, className, dataJS }).append( + el("code", { className: "language-"+language, textContent: content }) + ); +} +let is_registered= {}; +/** @param {string} page_id */ +function registerClientPart(page_id){ + if(is_registered[page_id]) return; + + document.head.append( + el("script", { src: "https://cdn.jsdelivr.net/npm/shiki", defer: true }), + ); + registerClientFile( + new URL("./code.js.js", import.meta.url), + el("script", { type: "module" }) + ); + is_registered[page_id]= true; +} diff --git a/docs_src/components/code.js.js b/docs_src/components/code.js.js new file mode 100644 index 0000000..247a5d1 --- /dev/null +++ b/docs_src/components/code.js.js @@ -0,0 +1,12 @@ +const highlighter= await shiki.getHighlighter({ + theme: "css-variables", + langs: ["js", "ts", "css", "html", "shell"], +}); +const codeBlocks= document.querySelectorAll('code[class*="language-"]'); + +codeBlocks.forEach((block)=> { + const lang= block.className.replace("language-", ""); + block.parentElement.dataset.js= "done"; + const html= highlighter.codeToHtml(block.textContent, { lang }); + block.innerHTML= html; +}); diff --git a/docs_src/components/example.html.js b/docs_src/components/example.html.js index 4663835..71e7bd5 100644 --- a/docs_src/components/example.html.js +++ b/docs_src/components/example.html.js @@ -1,59 +1,50 @@ -let is_registered= {}; -import { styles } from "../index.css.js"; -export const css= styles().scope(example).css` +import { styles } from "../ssr.js"; +styles.scope(example).css` :host{ - grid-column: 1/-1; + grid-column: full-main; width: 100%; max-width: calc(9/5 * var(--body-max-width)); height: calc(3/5 * var(--body-max-width)); margin-inline: auto; } +.CodeMirror, .CodeMirror-gutters { + background: #212121 !important; + border: 1px solid white; +} ` import { el } from "deka-dom-el"; +import { code } from "./code.html.js"; /** * Prints code to the page and registers flems to make it interactive. * @param {object} attrs * @param {URL} attrs.src Example code file path - * @param {string} [attrs.language="javascript"] Language of the code + * @param {"js"|"ts"|"html"|"css"} [attrs.language="js"] Language of the code * @param {string} attrs.page_id ID of the page - * @param {import("../types.d.ts").registerClientFile} attrs.registerClientFile * */ -export function example({ src, language= "javascript", page_id, registerClientFile }){ - registerClientPart(page_id, registerClientFile); - const code= s.cat(src).toString() +export function example({ src, language= "js", page_id }){ + registerClientPart(page_id); + const content= s.cat(src).toString() .replaceAll(' from "../../../index-with-signals.js";', ' from "https://cdn.jsdelivr.net/gh/jaandrle/deka-dom-el/dist/esm-with-signals.js";'); const id= "code-"+Math.random().toString(36).slice(2, 7); return el().append( - el("div", { id, className: example.name }).append( - el("pre").append( - el("code", { className: "language-"+language, textContent: code }) - ) - ), - elCode({ id, content: code }) + el(code, { id, content, language, className: example.name }), + elCode({ id, content, extension: "."+language }) ); } -function elCode({ id, content }){ +function elCode({ id, content, extension: name }){ const options= JSON.stringify({ - files: [{ name: ".js", content }], + files: [{ name, content }], toolbar: false }); return el("script", `Flems(document.getElementById("${id}"), JSON.parse(${JSON.stringify(options)}));`); } -function registerClientPart(page_id, registerClientFile){ +let is_registered= {}; +/** @param {string} page_id */ +function registerClientPart(page_id){ if(is_registered[page_id]) return; - //★ Highlite code when no flems? document.head.append( el("script", { src: "https://flems.io/flems.html", type: "text/javascript", charset: "utf-8" }), - //★ el("script", { src: "https://cdn.jsdelivr.net/npm/shiki", defer: true }), ); - const d= el("div"); - /** @param {HTMLDivElement} a */ - const f= (a)=> a; - f(d); //← - //★ egisterClientFile( - //★ new URL("./example.js.js", import.meta.url), - //★ el("script", { type: "module" }) - //★ ; is_registered[page_id]= true; } diff --git a/docs_src/components/example.js.js b/docs_src/components/example.js.js deleted file mode 100644 index 276f2c4..0000000 --- a/docs_src/components/example.js.js +++ /dev/null @@ -1,19 +0,0 @@ -const langs= { - javascript: 'js', - js: 'js', - html: 'html', -}; - -const highlighter= await shiki.getHighlighter({ - theme: 'css-variables', - langs: ['js', 'html', 'shell'], -}); -const codeBlocks= document.querySelectorAll('pre code[class*="language-"]'); - -codeBlocks.forEach((block)=> { - const lang= block.className.replace('language-', ''); - const html= highlighter.codeToHtml(block.textContent, { - lang: langs[lang] || lang, - }); - block.innerHTML= html; -}); diff --git a/docs_src/components/prevNext.html.js b/docs_src/components/prevNext.html.js new file mode 100644 index 0000000..a61472f --- /dev/null +++ b/docs_src/components/prevNext.html.js @@ -0,0 +1,41 @@ +import { pages, styles } from "../ssr.js"; +styles.scope(prevNext).css` +:host{ + display: grid; + grid-template-columns: 1fr 2fr 1fr; + margin-top: 1rem; + border-top: 1px solid var(--border); +} +:host [rel=prev]{ + grid-column: 1; +} +:host [rel=next]{ + grid-column: 3; + text-align: right; +} +`; +import { el } from "../../index.js"; +/** + * @param {import("../types.d.ts").Info} page + * */ +export function prevNext(page){ + const page_index= pages.indexOf(page); + return el("div", { className: prevNext.name }).append( + el(pageLink, { rel: "prev", page: pages[page_index-1] }), + el(pageLink, { rel: "next", page: pages[page_index+1] }) + ); +} +/** + * @param {Object} attrs + * @param {"prev"|"next"} attrs.rel + * @param {import("../types.d.ts").Info} [attrs.page] + * */ +function pageLink({ rel, page }){ + if(!page) return el(); + let { href, title, description }= page; + return el("a", { rel, href, title: description }).append( + rel==="next" ?"(next) " : "", + title, + rel==="prev" ? " (previous)" : "", + ); +} diff --git a/docs_src/elements.html.js b/docs_src/elements.html.js index 023a648..20394e0 100644 --- a/docs_src/elements.html.js +++ b/docs_src/elements.html.js @@ -1,22 +1,16 @@ +import "./global.css.js"; import { el } from "deka-dom-el"; -import { styles, common } from "./index.css.js"; -import { example, css as example_css } from "./components/example.html.js"; -export const css= styles() -.include(common) -.css` -.note{ - font-size: .9rem; - font-style: italic; -} -` -.include(example_css); +import { example } from "./components/example.html.js"; +/** @param {string} url */ +const fileURL= url=> new URL(url, import.meta.url); import { header } from "./layout/head.html.js"; +import { prevNext } from "./components/prevNext.html.js"; /** @param {import("./types.d.ts").PageAttrs} attrs */ -export function page({ pkg, info, path_target, pages, registerClientFile }){ +export function page({ pkg, info }){ const page_id= info.id; return el().append( - el(header, { info, pkg, path_target, pages }), + el(header, { info, pkg }), el("main").append( el("h2", "Native JavaScript DOM elements creations"), el("p", "Let’s go through all patterns we would like to use and what needs to be improved for better experience."), @@ -36,12 +30,12 @@ export function page({ pkg, info, path_target, pages, registerClientFile }){ el("abbr", { textContent: "IDL", title: "Interface Description Language" }) ), "." ), - el(example, { src: new URL("./components/examples/nativeCreateElement.js", import.meta.url), page_id, registerClientFile }), + el(example, { src: fileURL("./components/examples/nativeCreateElement.js"), page_id }), el("p").append( "To make this easier, you can use the ", el("code", "el"), " function. ", "Internally in basic examples, it is wrapper around ", el("code", "assign(document.createElement(…), { … })"), "." ), - el(example, { src: new URL("./components/examples/dekaCreateElement.js", import.meta.url), page_id, registerClientFile }), + el(example, { src: fileURL("./components/examples/dekaCreateElement.js"), page_id }), el("p").append( "The ", el("code", "assign"), " function provides improved behaviour of ", el("code", "Object.assign()"), ". ", "You can declaratively sets any IDL and attribute of the given element. ", @@ -82,27 +76,30 @@ export function page({ pkg, info, path_target, pages, registerClientFile }){ el("p").append( "For processing, the ", el("code", "assign"), " internally uses ", el("code", "assignAttribute"), " and ", el("code", "classListDeclarative"), "." ), - el(example, { src: new URL("./components/examples/dekaAssign.js", import.meta.url), page_id, registerClientFile }), + el(example, { src: fileURL("./components/examples/dekaAssign.js"), page_id }), el("h3", "Native JavaScript templating"), el("p", "By default, the native JS has no good way to define HTML template using DOM API:"), - el(example, { src: new URL("./components/examples/nativeAppend.js", import.meta.url), page_id, registerClientFile }), + el(example, { src: fileURL("./components/examples/nativeAppend.js"), page_id }), el("p").append( "This library therefore overwrites the ", el("code", "append"), " method of created elements to always return parent element." ), - el(example, { src: new URL("./components/examples/dekaAppend.js", import.meta.url), page_id, registerClientFile }), + el(example, { src: fileURL("./components/examples/dekaAppend.js"), page_id }), - el("h2", "Creating advanced (reactive) templates and components"), - - el("h3", "Basic components"), + el("h3", "Basic (state-less) components"), el("p").append( "You can use functions for encapsulation (repeating) logic. ", "The ", el("code", "el"), " accepts function as first argument. ", "In that case, the function should return dom elements and the second argument for ", el("code", "el"), " is argument for given element." ), - el(example, { src: new URL("./components/examples/dekaBasicComponent.js", import.meta.url), page_id, registerClientFile }), - el("p", "It is nice to use similar naming convention as native DOM API.") + el(example, { src: fileURL("./components/examples/dekaBasicComponent.js"), page_id }), + el("p", "It is nice to use similar naming convention as native DOM API."), + + el("h3", "Creating non-HTML elements"), + // example & notes + + el(prevNext, info) ) ); } diff --git a/docs/elements.css b/docs_src/global.css.js similarity index 79% rename from docs/elements.css rename to docs_src/global.css.js index 2ebc7e0..1110657 100644 --- a/docs/elements.css +++ b/docs_src/global.css.js @@ -1,3 +1,5 @@ +import { styles } from "./ssr.js"; +styles.scope(import.meta.url).css` @import url(https://cdn.simplecss.org/simple.min.css); :root{ --body-max-width: 45rem; @@ -38,21 +40,21 @@ body > nav{ flex-flow: column nowrap; } body > nav { - font-size:1rem; - line-height:2; - padding:1rem 0 0 0 + font-size: 1rem; + line-height: 2; + padding: 1rem 0 0 0; } body > nav ol, body > nav ul { - align-content:space-around; - align-items:center; - display:flex; - flex-direction:row; - flex-wrap:wrap; - justify-content:center; - list-style-type:none; - margin:0; - padding:0 + align-content: space-around; + align-items: center; + display: flex; + flex-direction: row; + flex-wrap: wrap; + justify-content: center; + list-style-type: none; + margin: 0; + padding: 0; } body > nav ol li, body > nav ul li { @@ -96,10 +98,13 @@ body > nav a:hover{ main{ grid-area: content; display: grid; - grid-template-columns: 1fr min(var(--body-max-width), 90%) 1fr; + grid-template-columns: + [full-main-start] 1fr + [main-start] min(var(--body-max-width), 90%) [main-end] + 1fr [full-main-end]; } main > *{ - grid-column: 2; + grid-column: main; } .icon { vertical-align: sub; @@ -116,10 +121,4 @@ main > *{ font-size: .9rem; font-style: italic; } -.example{ - grid-column: 1/-1; - width: 100%; - max-width: calc(9/5 * var(--body-max-width)); - height: calc(3/5 * var(--body-max-width)); - margin-inline: auto; -} \ No newline at end of file +`; diff --git a/docs_src/index.css.js b/docs_src/index.css.js deleted file mode 100644 index 4ca22cc..0000000 --- a/docs_src/index.css.js +++ /dev/null @@ -1,145 +0,0 @@ -const scopes= new WeakSet(); -const s= { - scope(s){ - if(!scopes.has(s)){ - scopes.add(s); - this.host= s.name; - } - return this; - }, - css(...a){ - let c= css(...a); - if(this.host){ - c= c.replaceAll(":host", "."+this.host); - this.host= ""; - } - if(this.content) this.content+= "\n"; - this.content+= c; - return this; - }, - include(...i){ - if(this.content) this.content+= "\n"; - this.content+= i.map(i=> typeof i === "string" ? i : i.content).join("\n"); - return this; - } -}; -export function css(...a){ - return String.raw(...a).trim(); -} -export function styles(){ return Object.assign(Object.create(s), { content: "" }); } -export const common= css` -@import url(https://cdn.simplecss.org/simple.min.css); -:root{ - --body-max-width: 45rem; - --marked: #fb3779; - --code: #0d47a1; - --accent: #d81b60; -} -@media (prefers-color-scheme:dark) { - :root { - --accent: #f06292; - --code: #62c1f0; - } -} -body { - grid-template-columns: 100%; - grid-template-areas: "header" "sidebar" "content"; -} -@media (min-width:768px) { - body{ - grid-template-rows: auto auto; - grid-template-columns: calc(var(--body-max-width) / 3) auto; - grid-template-areas: - "header header" - "sidebar content" - } -} -body > *{ - grid-column: unset; -} -body > header{ - grid-area: header; - padding: 0; -} -body > nav{ - grid-area: sidebar; - background-color: var(--accent-bg); - display: flex; - flex-flow: column nowrap; -} -body > nav { - font-size:1rem; - line-height:2; - padding:1rem 0 0 0 -} -body > nav ol, -body > nav ul { - align-content:space-around; - align-items:center; - display:flex; - flex-direction:row; - flex-wrap:wrap; - justify-content:center; - list-style-type:none; - margin:0; - padding:0 -} -body > nav ol li, -body > nav ul li { - display:inline-block -} -body > nav a, -body > nav a:visited { - margin: 0 .5rem 1rem .5rem; - border: 1px solid currentColor; - border-radius: var(--standard-border-radius); - color: var(--text-light); - display: inline-block; - padding: .1rem 1rem; - text-decoration: none; - cursor: pointer; - transition: all .15s; -} -body > nav a.current, -body > nav a[aria-current=page] { - background-color: var(--bg); - color: var(--text); -} -body > nav a:hover{ - background-color: var(--bg); - color: var(--accent); -} -@media only screen and (max-width:720px) { - body > nav{ - flex-flow: row wrap; - padding-block: .5rem; - } - body > nav a { - border:none; - text-decoration:underline; - margin-block: .1rem; - padding-block:.1rem; - line-height: 1rem; - font-size: .9rem; - } -} -main{ - grid-area: content; - display: grid; - grid-template-columns: 1fr min(var(--body-max-width), 90%) 1fr; -} -main > *{ - grid-column: 2; -} -.icon { - vertical-align: sub; - padding-right: .25rem; - display: inline-block; - width: 1em; - height: 1.3em; - margin-right: 0.2rem; - stroke-width: 0; - stroke: currentColor; - fill: currentColor; -} -`; diff --git a/docs_src/index.html.js b/docs_src/index.html.js index 5ad98c3..d5f36df 100644 --- a/docs_src/index.html.js +++ b/docs_src/index.html.js @@ -1,25 +1,18 @@ import { el } from "deka-dom-el"; -import { styles, common } from "./index.css.js"; -import { example, css as example_css } from "./components/example.html.js"; -export const css= styles() -.include(common) -.css` -.note{ - font-size: .9rem; - font-style: italic; -} -` -.include(example_css); +import "./global.css.js"; +import { example } from "./components/example.html.js"; import { header } from "./layout/head.html.js"; +import { prevNext } from "./components/prevNext.html.js"; /** @param {import("./types.d.ts").PageAttrs} attrs */ -export function page({ pkg, info, path_target, pages, registerClientFile }){ +export function page({ pkg, info }){ const page_id= info.id; return el().append( - el(header, { info, pkg, path_target, pages }), + el(header, { info, pkg }), el("main").append( - el("p", "The library tries to provide pure JavaScript tool(s) to create reactive interfaces. "), - el(example, { src: new URL("./components/examples/helloWorld.js", import.meta.url), page_id, registerClientFile }), + el("p", "The library tries to provide pure JavaScript tool(s) to create reactive interfaces."), + el(example, { src: new URL("./components/examples/helloWorld.js", import.meta.url), page_id }), + el(prevNext, info) ) ); } diff --git a/docs_src/layout/head.html.js b/docs_src/layout/head.html.js index 1a60d6e..58e1a3f 100644 --- a/docs_src/layout/head.html.js +++ b/docs_src/layout/head.html.js @@ -1,4 +1,5 @@ -import { el, elNS, scope } from "deka-dom-el"; +import { el, elNS } from "deka-dom-el"; +import { pages } from "../ssr.js"; /** * @param {object} def * @param {import("../types.d.ts").Info} def.info @@ -6,12 +7,12 @@ import { el, elNS, scope } from "deka-dom-el"; * @param {string} def.pkg.name * @param {string} def.pkg.description * @param {string} def.pkg.homepage - * @param {{ root: string, css: string}} def.path_target Final URL where the page will be rendered. - * @param {import("../types.js").Pages} def.pages * */ -export function header({ info: { id, title, description }, pkg, path_target, pages }){ +export function header({ info: { href, title, description }, pkg }){ title= `\`${pkg.name}\` — ${title}`; - document.head.append(head({ id, title, description, pkg, path_target })); + document.head.append( + head({ title, description, pkg }) + ); return el().append( el("header").append( el("h1", title), @@ -23,23 +24,29 @@ export function header({ info: { id, title, description }, pkg, path_target, pag "GitHub" ), ...pages.map((p, i)=> el("a", { - href: p.id==="index" ? "./" : p.id, + href: p.href==="index" ? "./" : p.href, textContent: (i+1) + ". " + p.title, title: p.description, - classList: { current: p.id===id } + classList: { current: p.href===href } })) ) ); } -function head({ id, title, description, pkg, path_target }){ +function head({ title, description, pkg }){ return el().append( el("meta", { name: "viewport", content: "width=device-width, initial-scale=1" }), - el("link", { rel: "stylesheet", href: stylesheetHref(path_target, id) }), - el("meta", { name: "description", content: description }), + el("title", title), + el(metaAuthor), el(metaTwitter, pkg), el(metaFacebook, pkg), - el("title", title), + ); +} +function metaAuthor(){ + return el().append( + el("meta", { name: "author", content: "Jan Andrle" }), + el("link", { type: "text/plain", rel: "author", href: "https://jaandrle.github.io/humans.txt" }), + el("meta", { name: "generator", content: "deka-dom-el" }), ); } function metaTwitter({ name, description, homepage }){ @@ -62,9 +69,6 @@ function metaFacebook({ name, description, homepage }){ el("meta", { name: "og:creator", content: "@jaandrle" }), ); } -function stylesheetHref(path_target, name){ - return path_target.css.replace(path_target.root, "")+name+".css"; -} function iconGitHub(){ const el= elNS("http://www.w3.org/2000/svg"); return el("svg", { className: "icon", viewBox: "0 0 32 32" }).append( diff --git a/docs_src/ssr.js b/docs_src/ssr.js new file mode 100644 index 0000000..5a8eff8 --- /dev/null +++ b/docs_src/ssr.js @@ -0,0 +1,77 @@ +export const path_target= { + root: "docs/", + css: "docs/" +}; +export const pages= [ + { id: "index", href: "./", title: "Introduction", description: "Introducing a library and motivations." }, + { id: "elements", href: "elements", title: "Elements", description: "Basic concepts of elements modifications and creations." } +]; +/** + * @typedef registerClientFile + * @type {function} + * @param {URL} url + * @param {HTMLScriptElement|HTMLLinkElement} [element_head] + * */ +export function registerClientFile(url, element_head){ + const file_name= url.pathname.split("/").pop(); + s.cat(url).to(path_target.root+file_name); + + if(!element_head) return; + element_head[element_head instanceof HTMLScriptElement ? "src" : "href"]= file_name; + document.head.append( + element_head + ); +} + +const events= { + oneachrender: new Set(), + onssrend: new Set() +}; +/** @param {keyof typeof events} name @param {function} listener */ +export function addEventListener(name, listener){ + events[name].add(listener); +} +/** @param {keyof typeof events} name @param {any} a */ +export function dispatchEvent(name, a){ + const ls= events[name]; + ls.forEach(l=> l(a)); + if(name!=="oneachrender") + ls.clear(); +} + +const scopes= new Set(); +export const styles= { + element: null, + name: "global.css", + get location(){ return path_target.css.replace(path_target.root, "")+this.name; }, + content: "", + + skip: false, + /** @param {function|string} s */ + scope(s){ + if(scopes.has(s)){ this.skip= true; return this; } + + scopes.add(s); + if(typeof s==="function") this.host= s.name; + return this; + }, + /** @param {Parameters} a */ + css(...a){ + if(this.skip){ this.skip= false; return this; } + + let c= css(...a); + if(this.host){ + c= c.replaceAll(":host", "."+this.host); + this.host= ""; + } + if(this.content) this.content+= "\n"; + this.content+= c; + return this; + } +}; +addEventListener("onssrend", ()=> scopes.clear()); +addEventListener("oneachrender", ()=> document.head.append( + Object.assign(document.createElement("link"), { rel: "stylesheet", href: styles.location }) +)); +/** @type {typeof String.raw} */ +function css(...a){ return String.raw(...a).trim(); } diff --git a/docs_src/types.d.ts b/docs_src/types.d.ts index 2d831f0..1773832 100644 --- a/docs_src/types.d.ts +++ b/docs_src/types.d.ts @@ -2,6 +2,7 @@ export type Pkg= Record export type Info= { id: string, + href: string, title: string, description: string, } diff --git a/examples/components/webComponent.js b/examples/components/webComponent.js index 8788bc5..487f05a 100644 --- a/examples/components/webComponent.js +++ b/examples/components/webComponent.js @@ -48,7 +48,7 @@ lifecycleToEvents(CustomHTMLTestElement) customElements.define(CustomHTMLTestElement.tagName, CustomHTMLTestElement); function customElementRender(_this, render){ - scope.push({ scope: _this, host: (...a)=> a.length ? a[0](_this) : _this, inherit_host: true }); + scope.push({ scope: _this, host: (...a)=> a.length ? a[0](_this) : _this, custom_element: _this }); const out= render(_this); scope.pop(); return out; diff --git a/index.d.ts b/index.d.ts index ea781b0..ffc98eb 100644 --- a/index.d.ts +++ b/index.d.ts @@ -127,7 +127,7 @@ interface On{ } export const on: On; -type Scope= { scope: Node | Function | Object, host: ddeElementModifier, prevent: boolean, inherit_host: boolean, } +type Scope= { scope: Node | Function | Object, host: ddeElementModifier, custom_element: false | HTMLElement, prevent: boolean } /** Current scope created last time the `el(Function)` was invoke. (Or {@link scope.push}) */ export const scope: { current: Scope, @@ -438,4 +438,8 @@ declare global{ /** Elements returned by {@link el} return parent element for `.append` method. **Regullarly created elements are untouched.** */ append: ddeAppend; } + interface SVGElement{ + /** Elements returned by {@link el} return parent element for `.append` method. **Regullarly created elements are untouched.** */ + append: ddeAppend; + } } diff --git a/jsdom.d.ts b/jsdom.d.ts index 9d4981d..a623a93 100644 --- a/jsdom.d.ts +++ b/jsdom.d.ts @@ -1,6 +1,6 @@ import { el, assign, on } from "./index.d"; export * from "./index.d"; -export function register(dom: typeof document): Promise<{ +export function register(dom: JSDOM): Promise<{ el: typeof el, assign: typeof assign, on: typeof on diff --git a/jsdom.js b/jsdom.js index b5684fb..75ee31e 100644 --- a/jsdom.js +++ b/jsdom.js @@ -1,8 +1,9 @@ //TODO: https://www.npmjs.com/package/html-element -import { prop_process } from './src/dom-common.js'; -const { setDeleteAttr }= prop_process; +import { enviroment } from './src/dom-common.js'; +enviroment.ssr= true; +const { setDeleteAttr }= enviroment; /** @param {HTMLElement} obj */ -prop_process.setDeleteAttr= function(obj, prop, value){ +enviroment.setDeleteAttr= function(obj, prop, value){ if("value"===prop) return obj.setAttribute(prop, value); if("checked"!==prop) return setDeleteAttr(obj, prop, value); if(value) return obj.setAttribute(prop, ""); diff --git a/src/dom-common.js b/src/dom-common.js index 1c6b969..2e8e1ed 100644 --- a/src/dom-common.js +++ b/src/dom-common.js @@ -1,4 +1,4 @@ -export const prop_process= { setDeleteAttr }; +export const enviroment= { setDeleteAttr, ssr: false }; import { isUndef } from './helpers.js'; function setDeleteAttr(obj, prop, val){ /* Issue diff --git a/src/dom.js b/src/dom.js index 984565f..feb8695 100644 --- a/src/dom.js +++ b/src/dom.js @@ -1,11 +1,12 @@ import { signals } from "./signals-common.js"; +import { enviroment } from './dom-common.js'; /** @type {{ scope: object, prevent: boolean, host: function }[]} */ const scopes= [ { scope: document.body, host: c=> c ? c(document.body) : document.body, + custom_element: false, prevent: true, - inherit_host: false, } ]; export const scope= { get current(){ return scopes[scopes.length-1]; }, @@ -25,7 +26,7 @@ export const scope= { }; let namespace; export function createElement(tag, attributes, ...modifiers){ - /* jshint maxcomplexity: 16 */ + /* jshint maxcomplexity: 15 */ const s= signals(this); let scoped= 0; let el, el_host; @@ -35,15 +36,14 @@ export function createElement(tag, attributes, ...modifiers){ switch(true){ case typeof tag==="function": { scoped= 1; - const { inherit_host, host: hostParent }= scope.current; - const host= inherit_host ? hostParent : c=> c ? (scoped===1 ? modifiers.unshift(c) : c(el_host), undefined) : el_host; - scope.push({ scope: tag, host, inherit_host }); + scope.push({ scope: tag, host: c=> c ? (scoped===1 ? modifiers.unshift(c) : c(el_host), undefined) : el_host }); el= tag(attributes || undefined); const is_fragment= el instanceof DocumentFragment; + if(el.nodeName==="#comment") break; const el_mark= createElement.mark({ type: "component", name: tag.name, - host: is_fragment ? "this" : ( el.nodeName==="#comment" ? "previousLater" : "parentElement" ) + host: is_fragment ? "this" : "parentElement", }); el.prepend(el_mark); if(is_fragment) el_host= el_mark; @@ -66,6 +66,7 @@ export function createElement(tag, attributes, ...modifiers){ * @param {boolean} [is_open=false] * */ createElement.mark= function(attrs, is_open= false){ + if(enviroment.ssr) attrs.ssr= true; attrs= Object.entries(attrs).map(([ n, v ])=> n+`="${v}"`).join(" "); const end= is_open ? "" : "/"; const out= document.createComment(``); @@ -91,8 +92,7 @@ export function createElementNS(ns){ } export { createElementNS as elNS }; -import { prop_process } from './dom-common.js'; -const { setDeleteAttr }= prop_process; +const { setDeleteAttr }= enviroment; const assign_context= new WeakMap(); export function assign(element, ...attributes){ if(!attributes.length) return element; diff --git a/src/events.js b/src/events.js index 8ae20b3..c4b3585 100644 --- a/src/events.js +++ b/src/events.js @@ -13,14 +13,17 @@ export function on(event, listener, options){ const c_ch_o= connectionsChangesObserverConstructor(); const els_attribute_store= new WeakSet(); +import { scope } from "./dom.js"; import { onAbort } from './helpers.js'; //TODO: cleanUp when event before abort? on.connected= function(listener, options){ + const { custom_element }= scope.current; const name= "connected"; if(typeof options !== "object") options= {}; options.once= true; return function registerElement(element){ + if(custom_element) element= custom_element; const event= "dde:"+name; element.addEventListener(event, listener, options); if(element.__dde_lifecycleToEvents) return element; @@ -32,11 +35,13 @@ on.connected= function(listener, options){ }; }; on.disconnected= function(listener, options){ + const { custom_element }= scope.current; const name= "disconnected"; if(typeof options !== "object") options= {}; options.once= true; return function registerElement(element){ + if(custom_element) element= custom_element; const event= "dde:"+name; element.addEventListener(event, listener, options); if(element.__dde_lifecycleToEvents) return element;