sprae 10.8.0 → 10.8.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/directive/if.js +16 -22
- package/dist/sprae.js +16 -22
- package/dist/sprae.min.js +1 -1
- package/package.json +1 -1
- package/readme.md +4 -4
package/directive/if.js
CHANGED
|
@@ -5,37 +5,31 @@ import { effect } from "../signal.js";
|
|
|
5
5
|
// as for :if :with - :if must init first, since it is lazy, to avoid initializing component ahead of time by :with
|
|
6
6
|
// we consider :with={x} :if={x} case insignificant
|
|
7
7
|
const _prevIf = Symbol("if");
|
|
8
|
-
directive.if = (
|
|
9
|
-
let next =
|
|
8
|
+
directive.if = (el, evaluate, state) => {
|
|
9
|
+
let next = el.nextElementSibling,
|
|
10
10
|
holder = document.createTextNode(''),
|
|
11
|
+
curEl, ifEl, elseEl;
|
|
11
12
|
|
|
12
|
-
|
|
13
|
-
none = [], cur = none, ifs, elses;
|
|
13
|
+
el.replaceWith(holder)
|
|
14
14
|
|
|
15
|
-
ifEl.
|
|
16
|
-
|
|
17
|
-
ifs = ifEl.content ? [frag(ifEl)] : [ifEl]
|
|
15
|
+
ifEl = el.content ? frag(el) : el
|
|
16
|
+
memo.set(ifEl, null) // mark all el as fake-spraed, because we have to sprae for real on insert
|
|
18
17
|
|
|
19
18
|
if (next?.hasAttribute(":else")) {
|
|
20
19
|
next.removeAttribute(":else");
|
|
21
20
|
// if next is :else :if - leave it for its own :if handler
|
|
22
|
-
if (next.hasAttribute(":if"))
|
|
23
|
-
|
|
24
|
-
} else elses = none;
|
|
25
|
-
|
|
26
|
-
// we mark all els as fake-spraed, because we have to sprae for real on insert
|
|
27
|
-
for (let el of [...ifs, ...elses]) memo.set(el, null)
|
|
21
|
+
if (!next.hasAttribute(":if")) next.remove(), elseEl = next.content ? frag(next) : next, memo.set(elseEl, null)
|
|
22
|
+
}
|
|
28
23
|
|
|
29
24
|
return effect(() => {
|
|
30
|
-
const
|
|
31
|
-
if (next) next[_prevIf] =
|
|
32
|
-
if (
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
sprae(el, state)
|
|
25
|
+
const newEl = evaluate(state) ? ifEl : el[_prevIf] ? null : elseEl;
|
|
26
|
+
if (next) next[_prevIf] = newEl === ifEl
|
|
27
|
+
if (curEl != newEl) {
|
|
28
|
+
curEl?.remove()
|
|
29
|
+
if (curEl = newEl) {
|
|
30
|
+
holder.before(curEl.content || curEl)
|
|
31
|
+
memo.get(curEl) === null && memo.delete(curEl) // remove fake memo to sprae as new
|
|
32
|
+
sprae(curEl, state)
|
|
39
33
|
}
|
|
40
34
|
}
|
|
41
35
|
});
|
package/dist/sprae.js
CHANGED
|
@@ -277,32 +277,26 @@ var untracked2 = (fn, prev, v) => (prev = current, current = null, v = fn(), cur
|
|
|
277
277
|
|
|
278
278
|
// directive/if.js
|
|
279
279
|
var _prevIf = Symbol("if");
|
|
280
|
-
directive.if = (
|
|
281
|
-
let next =
|
|
282
|
-
|
|
283
|
-
|
|
280
|
+
directive.if = (el, evaluate, state) => {
|
|
281
|
+
let next = el.nextElementSibling, holder = document.createTextNode(""), curEl, ifEl, elseEl;
|
|
282
|
+
el.replaceWith(holder);
|
|
283
|
+
ifEl = el.content ? frag(el) : el;
|
|
284
|
+
memo.set(ifEl, null);
|
|
284
285
|
if (next?.hasAttribute(":else")) {
|
|
285
286
|
next.removeAttribute(":else");
|
|
286
|
-
if (next.hasAttribute(":if"))
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
next.remove(), elses = next.content ? [frag(next)] : [next];
|
|
290
|
-
} else
|
|
291
|
-
elses = none;
|
|
292
|
-
for (let el of [...ifs, ...elses])
|
|
293
|
-
memo.set(el, null);
|
|
287
|
+
if (!next.hasAttribute(":if"))
|
|
288
|
+
next.remove(), elseEl = next.content ? frag(next) : next, memo.set(elseEl, null);
|
|
289
|
+
}
|
|
294
290
|
return effect(() => {
|
|
295
|
-
const
|
|
291
|
+
const newEl = evaluate(state) ? ifEl : el[_prevIf] ? null : elseEl;
|
|
296
292
|
if (next)
|
|
297
|
-
next[_prevIf] =
|
|
298
|
-
if (
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
memo.get(el) === null && memo.delete(el);
|
|
305
|
-
sprae(el, state);
|
|
293
|
+
next[_prevIf] = newEl === ifEl;
|
|
294
|
+
if (curEl != newEl) {
|
|
295
|
+
curEl?.remove();
|
|
296
|
+
if (curEl = newEl) {
|
|
297
|
+
holder.before(curEl.content || curEl);
|
|
298
|
+
memo.get(curEl) === null && memo.delete(curEl);
|
|
299
|
+
sprae(curEl, state);
|
|
306
300
|
}
|
|
307
301
|
}
|
|
308
302
|
});
|
package/dist/sprae.min.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
var e,t,r,l,n,
|
|
1
|
+
var e,t,r,l,n,s=Object.defineProperty,o=Symbol("signals"),a=Symbol("length");function i(t,r){if(!t)return t;if(t[o])return t;if(Array.isArray(t))return function(t){let r;if(t[o])return t;let l=e(t.length),n=Array(t.length).fill();const s=new Proxy(n,{get:(s,c)=>"symbol"==typeof c?c===a?l:c===o?n:n[c]:"length"===c?u[r]?l.peek():l.value:(r=c,n[c]?n[c].valueOf():c<n.length?(n[c]=e(i(t[c]))).value:void 0),set(e,t,r){if("length"===t){for(let e=r,t=n.length;e<t;e++)delete s[e];return l.value=n.length=r,!0}return c(n,t,r),t>=l.peek()&&(l.value=n.length=Number(t)+1),!0},deleteProperty:(e,t)=>(n[t]&&f(n,t),1)});return s}(t);if(t.constructor!==Object)return t;let l={...r?.[o]},s=e(Object.values(t).length);const p=new Proxy(l,{get:(e,t)=>t===a?s:t===o?l:l[t]?.valueOf(),set:(e,t,r,n)=>(n=l[t],c(l,t,r),n??++s.value,1),deleteProperty:(e,t)=>(l[t]&&(f(l,t),s.value--),1),ownKeys:()=>(s.value,Reflect.ownKeys(l))});for(let e in t){const r=Object.getOwnPropertyDescriptor(t,e);r?.get?(l[e]=n(r.get.bind(p)))._set=r.set?.bind(p):(l[e]=void 0,c(l,e,t[e]))}return p}var u={push:1,pop:1,shift:1,unshift:1,splice:1};function c(t,n,s){let o=t[n];if("_"===n[0])t[n]=s;else if(o)if(s===o.peek());else if(o._set)o._set(s);else if(Array.isArray(s)&&Array.isArray(o.peek())){const e=o.peek();e[a]?r((()=>{l((()=>{let t=0,r=s.length;for(;t<r;t++)e[t]=s[t];e.length=r}))})):o.value=s}else o.value=i(s);else t[n]=o=s?.peek?s:e(i(s))}function f(e,t){const r=e[t],l=r[Symbol.dispose];l&&delete r[Symbol.dispose],delete e[t],l?.()}var p=Symbol.dispose||=Symbol("dispose"),d={},y=new WeakMap;function h(e,t){if(!e?.childNodes)return;if(y.has(e))return Object.assign(y.get(e),t);const r=i(t||{}),l=[];return function e(t,n=t.parentNode){if(t.childNodes){for(let e=0;e<t.attributes?.length;){let s=t.attributes[e];if(":"===s.name[0]){t.removeAttribute(s.name);let e=s.name.slice(1).split(":");for(let n of e){let e=d[n]||d.default,o=e(t,(e.parse||g)(s.value,g),r,n);o&&l.push(o)}if(y.has(t))return t[p]&&l.push(t[p]);if(t.parentNode!==n)return}else e++}for(let r of[...t.childNodes])e(r,t)}}(e),y.has(e)||y.set(e,r),e[p]=()=>{for(;l.length;)l.pop()();y.delete(e)},r}var m,v={},g=(e,t,r)=>{if(r=v[e=e.trim()])return r;try{r=m(e)}catch(r){b(r,t,e)}return v[e]=r},b=(e,t,r="")=>{throw Object.assign(e,{message:`∴ ${e.message}\n\n${t}${r?`="${r}"\n\n`:""}`,expr:r})};h.use=s=>{s.signal&&function(s){e=s.signal,t=s.effect,n=s.computed,l=s.batch||(e=>e()),r=s.untracked||l}(s),s.compile&&(m=s.compile)};var k,A,w=e=>{if(!e.nodeType)return e;e.content.appendChild(document.createTextNode(""));let t=e.content.cloneNode(!0),r=[...e.attributes],l=[...t.childNodes];return{childNodes:l,content:t,remove:()=>t.append(...l),replaceWith(e){l[0].before(e),t.append(...l)},attributes:r,removeAttribute(e){r.splice(r.findIndex((t=>t.name===e)),1)}}},S={};((e,t)=>{for(var r in t)s(e,r,{get:t[r],enumerable:!0})})(S,{batch:()=>W,computed:()=>x,effect:()=>O,signal:()=>N,untracked:()=>j});var N=(e,t,r=new Set)=>((t={get value(){return k?.deps.push(r.add(k)),e},set value(t){if(t!==e){e=t;for(let e of r)A?A.add(e):e()}},peek:()=>e}).toJSON=t.then=t.toString=t.valueOf=()=>t.value,t),O=(e,t,r,l)=>(l=(r=l=>{t?.call?.(),l=k,k=r;try{t=e()}finally{k=l}}).deps=[],r(),e=>{for(t?.call?.();e=l.pop();)e.delete(r)}),x=(e,t=N(),r,l)=>((r={get value(){return l||=O((()=>t.value=e())),t.value},peek:t.peek}).toJSON=r.then=r.toString=r.valueOf=()=>r.value,r),W=e=>{let t=A;t||(A=new Set);try{e()}finally{if(!t){t=A,A=null;for(const e of t)e()}}},j=(e,t,r)=>(t=k,k=null,r=e(),k=t,r),T=Symbol("if");d.if=(e,r,l)=>{let n,s,o,a=e.nextElementSibling,i=document.createTextNode("");return e.replaceWith(i),s=e.content?w(e):e,y.set(s,null),a?.hasAttribute(":else")&&(a.removeAttribute(":else"),a.hasAttribute(":if")||(a.remove(),o=a.content?w(a):a,y.set(o,null))),t((()=>{const t=r(l)?s:e[T]?null:o;a&&(a[T]=t===s),n!=t&&(n?.remove(),(n=t)&&(i.before(n.content||n),null===y.get(n)&&y.delete(n),h(n,l)))}))},d.each=(e,[l,s,u],c)=>{const f=document.createTextNode("");e.replaceWith(f);let p,d,y=0;const m=n((()=>{d=null;let e=u(c);return"number"==typeof e&&(e=Array.from({length:e},((e,t)=>t+1))),e?.constructor===Object&&(d=Object.keys(e),e=Object.values(e)),e||[]})),v=()=>{r((()=>{let t=0,r=m.value,n=r.length;if(p&&!p[a]){for(let e of p[o]||[])e[Symbol.dispose]();p=null,y=0}if(n<y)p.length=n;else{if(p)for(;t<y;t++)p[t]=r[t];else p=r;for(;t<n;t++){p[t]=r[t];let n=t,a=i({[l]:p[o]?.[n]||p[n],[s]:d?d[n]:n},c),u=e.content?w(e):e.cloneNode(!0);f.before(u.content||u),h(u,a),((p[o]||=[])[t]||={})[Symbol.dispose]=()=>{u[Symbol.dispose](),u.remove()}}}y=n}))};let g=0;return t((()=>{m.value[a]?.value,g?g++:(v(),queueMicrotask((()=>(g&&v(),g=0))))}))},d.each.parse=(e,t)=>{let[r,l]=e.split(/\s+in\s+/),[n,s="$"]=r.split(/\s*,\s*/);return[n,s,t(l)]},d.ref=(e,t,r)=>{r[t]=e},d.ref.parse=e=>e,d.with=(e,r,l)=>{let n;return t((()=>{let t=r(l);h(e,n?t:n=i(t,l))}))},d.html=(e,t,r)=>{let l=t(r);if(!l)return;let n=(l.content||l).cloneNode(!0);e.replaceChildren(n),h(e,r)},d.text=(e,r,l)=>{if(e.content){let t=w(e);e!==t&&e.replaceWith(t.content),e=t.childNodes[0]}return t((()=>{let t=r(l);e.textContent=null==t?"":t}))},d.class=(e,r,l)=>{let n=new Set;return t((()=>{let t=r(l),s=new Set;t&&("string"==typeof t?t.split(" ").map((e=>s.add(e))):Array.isArray(t)?t.map((e=>e&&s.add(e))):Object.entries(t).map((([e,t])=>t&&s.add(e))));for(let t of n)s.has(t)?s.delete(t):e.classList.remove(t);for(let t of n=s)e.classList.add(t)}))},d.style=(e,r,l)=>{let n=e.getAttribute("style")||"";return n.endsWith(";")||(n+="; "),t((()=>{let t=r(l);if("string"==typeof t)e.setAttribute("style",n+t);else{e.setAttribute("style",n);for(let r in t)e.style.setProperty(r,t[r])}}))},d.default=(e,r,l,n)=>{if(!n.startsWith("on"))return t((()=>{let t=r(l);if(n)E(e,n,t);else for(let r in t)E(e,D(r),t[r])}));const s=n.split("..").map((t=>{let r={evt:"",target:e,test:()=>!0};return r.evt=(t.startsWith("on")?t.slice(2):t).replace(/\.(\w+)?-?([-\w]+)?/g,((e,t,l="")=>(r.test=$[t]?.(r,...l.split("-"))||r.test,""))),r}));if(1==s.length)return t((()=>f(r(l),s[0])));let o,a,i,u=0;const c=e=>{i=f((t=>(i(),a=e?.(t),(u=++u%s.length)?c(a):o&&c(o))),s[u])};return t((()=>(o=r(l),!i&&c(o),()=>o=null)));function f(e,{evt:t,target:r,test:l,defer:n,stop:s,prevent:o,immediate:a,...i}){n&&(e=n(e));const u=r=>{try{l(r)&&(s&&(a?r.stopImmediatePropagation():r.stopPropagation()),o&&r.preventDefault(),e?.(r))}catch(r){b(r,`:on${t}`,e)}};return r.addEventListener(t,u,i),()=>r.removeEventListener(t,u,i)}};var $={prevent(e){e.prevent=!0},stop(e){e.stop=!0},immediate(e){e.immediate=!0},once(e){e.once=!0},passive(e){e.passive=!0},capture(e){e.capture=!0},window(e){e.target=window},document(e){e.target=document},throttle(e,t){e.defer=e=>P(e,t?Number(t)||0:108)},debounce(e,t){e.defer=e=>_(e,t?Number(t)||0:108)},outside:e=>t=>{let r=e.target;return!(r.contains(t.target)||!1===t.target.isConnected||r.offsetWidth<1&&r.offsetHeight<1)},self:e=>t=>t.target===e.target,ctrl:(e,...t)=>e=>C.ctrl(e)&&t.every((t=>C[t]?C[t](e):e.key===t)),shift:(e,...t)=>e=>C.shift(e)&&t.every((t=>C[t]?C[t](e):e.key===t)),alt:(e,...t)=>e=>C.alt(e)&&t.every((t=>C[t]?C[t](e):e.key===t)),meta:(e,...t)=>e=>C.meta(e)&&t.every((t=>C[t]?C[t](e):e.key===t)),arrow:()=>C.arrow,enter:()=>C.enter,esc:()=>C.esc,tab:()=>C.tab,space:()=>C.space,delete:()=>C.delete,digit:()=>C.digit,letter:()=>C.letter,char:()=>C.char},C={ctrl:e=>e.ctrlKey||"Control"===e.key||"Ctrl"===e.key,shift:e=>e.shiftKey||"Shift"===e.key,alt:e=>e.altKey||"Alt"===e.key,meta:e=>e.metaKey||"Meta"===e.key||"Command"===e.key,arrow:e=>e.key.startsWith("Arrow"),enter:e=>"Enter"===e.key,esc:e=>e.key.startsWith("Esc"),tab:e=>"Tab"===e.key,space:e=>" "===e.key||"Space"===e.key||" "===e.key,delete:e=>"Delete"===e.key||"Backspace"===e.key,digit:e=>/^\d$/.test(e.key),letter:e=>/^\p{L}$/gu.test(e.key),char:e=>/^\S$/.test(e.key)},E=(e,t,r)=>{null==r||!1===r?e.removeAttribute(t):e.setAttribute(t,!0===r?"":"number"==typeof r||"string"==typeof r?r:"")},P=(e,t)=>{let r,l,n=s=>{r=!0,setTimeout((()=>{if(r=!1,l)return l=!1,n(s),e(s)}),t)};return t=>r?l=!0:(n(t),e(t))},_=(e,t)=>{let r;return l=>{clearTimeout(r),r=setTimeout((()=>{r=null,e(l)}),t)}},D=e=>e.replace(/[A-Z\u00C0-\u00D6\u00D8-\u00DE]/g,(e=>"-"+e.toLowerCase()));d.value=(e,r,l)=>{let n,s,o="text"===e.type||""===e.type?t=>e.setAttribute("value",e.value=null==t?"":t):"TEXTAREA"===e.tagName||"text"===e.type||""===e.type?t=>(n=e.selectionStart,s=e.selectionEnd,e.setAttribute("value",e.value=null==t?"":t),n&&e.setSelectionRange(n,s)):"checkbox"===e.type?t=>(e.checked=t,E(e,"checked",t)):"select-one"===e.type?t=>{for(let t in e.options)t.removeAttribute("selected");e.value=t,e.selectedOptions[0]?.setAttribute("selected","")}:t=>e.value=t;return t((()=>o(r(l))))},d.fx=(e,r,l)=>t((()=>r(l))),h.use(S),h.use({compile:e=>h.constructor("__scope",`with (__scope) { return ${e} };`)});var K=h;export{K as default};
|
package/package.json
CHANGED
package/readme.md
CHANGED
|
@@ -362,12 +362,12 @@ sprae.use({ compile })
|
|
|
362
362
|
|
|
363
363
|
## Hints
|
|
364
364
|
|
|
365
|
-
* To prevent [FOUC](https://en.wikipedia.org/wiki/Flash_of_unstyled_content) add `<style>[:each],[:if],[:else]
|
|
366
|
-
* Attributes order matters, eg. `<li :each="
|
|
365
|
+
* To prevent [FOUC](https://en.wikipedia.org/wiki/Flash_of_unstyled_content) add `<style>[:each],[:if],[:else] {visibility: hidden}</style>`
|
|
366
|
+
* Attributes order matters, eg. `<li :each="el in els" :text="el.name"></li>` is not the same as `<li :text="el.name" :each="el in els"></li>`
|
|
367
367
|
* To destroy state and detach sprae handlers, call `element[Symbol.dispose]()`.
|
|
368
368
|
* State getters/setters work as computed effects, eg. `sprae(el, { x:1, get x2(){ return this.x * 2} })`.
|
|
369
|
-
* `this` keyword is not used, to get access to current element use
|
|
370
|
-
* Async/await is not supported in attributes, it's a strong
|
|
369
|
+
* `this` keyword is not used, to get access to current element use `<input :ref="el" :text="el.value"/>`
|
|
370
|
+
* Async/await is not supported in attributes, it's a strong indicator you need to put these methods into state.
|
|
371
371
|
|
|
372
372
|
## Justification
|
|
373
373
|
|