sprae 2.5.3 → 2.5.5
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/package.json +2 -2
- package/r&d.md +31 -3
- package/readme.md +1 -1
- package/sprae.js +54 -34
- package/sprae.min.js +1 -1
- package/src/directives.js +21 -21
- package/test/test.js +22 -0
package/package.json
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "sprae",
|
|
3
3
|
"description": "DOM microhydration.",
|
|
4
|
-
"version": "2.5.
|
|
4
|
+
"version": "2.5.5",
|
|
5
5
|
"main": "src/index.js",
|
|
6
6
|
"module": "src/index.js",
|
|
7
7
|
"type": "module",
|
|
8
8
|
"dependencies": {
|
|
9
9
|
"@preact/signals-core": "^1.2.2",
|
|
10
10
|
"primitive-pool": "^2.0.0",
|
|
11
|
-
"signal-struct": "^1.
|
|
11
|
+
"signal-struct": "^1.9.0",
|
|
12
12
|
"swapdom": "^1.1.1"
|
|
13
13
|
},
|
|
14
14
|
"devDependencies": {
|
package/r&d.md
CHANGED
|
@@ -324,18 +324,20 @@
|
|
|
324
324
|
- need to match many syntax quirks, can be tedious
|
|
325
325
|
~ can be fine to limit expressions to meaningful default: why Proxy, generators, awaits, global access etc.
|
|
326
326
|
- Somewhat heavy to bundle
|
|
327
|
-
~ 1-2kb is not super-heavy, besides signal-struct
|
|
327
|
+
~ 1-2kb is not super-heavy, besides kicks out signal-struct (with preact signals?)
|
|
328
328
|
+ Scope is easier to provide: no need for signal proxy
|
|
329
329
|
+ Can detect access errors in advance
|
|
330
330
|
+ Syntax-level access to signals can be inavoidable: external signals still "leak in" (via arrays or etc.).
|
|
331
331
|
+ Updating simple objects should also rerender the template parts, not just signals.
|
|
332
332
|
+ Deps can be analyzed / implemented without signals
|
|
333
|
-
- Screwed up debugging / stacktrace (unless errored)
|
|
333
|
+
- Screwed up debugging / stacktrace (unless errored properly)
|
|
334
|
+
~+ can actually provide better trace since no internal framework stuff is shown
|
|
334
335
|
+ that "unlimits" returned struct, so that any property can be added/deleted.
|
|
335
336
|
- doesn't really save from `new (()=>{}).constructor` hack: we gotta substitute objects too.
|
|
336
337
|
+ allows easier handle of `:with="a=1,b=2,c=3"` - we just naturally get local variables without messup with global
|
|
337
338
|
+ we can even define locals without `let`...
|
|
338
339
|
- not having "comfy" compatible JS at hand: cognitive load of whole language "layer" in-between
|
|
340
|
+
+ allows `let a = 1; a;` case instead of `let a = 1; return a;`
|
|
339
341
|
|
|
340
342
|
2. Use sandboxed proxy
|
|
341
343
|
- tough evaluation
|
|
@@ -391,4 +393,30 @@
|
|
|
391
393
|
.equal Equal, =
|
|
392
394
|
.period Period, .
|
|
393
395
|
.slash Foward Slash, /
|
|
394
|
-
- conflict with dot-separated events
|
|
396
|
+
- conflict with dot-separated events
|
|
397
|
+
|
|
398
|
+
## [x] Writing props on elements (like ones in :each) -> nah, just use `:x="this.x=abc"`
|
|
399
|
+
|
|
400
|
+
1. `:x="abc"` creates property + attribute
|
|
401
|
+
- can be excessive pollution
|
|
402
|
+
|
|
403
|
+
2. `.x="abc"`
|
|
404
|
+
~ `:x.x=""` writes both property and attribute...
|
|
405
|
+
- conflicts with class selector
|
|
406
|
+
- blocks dot-separated values
|
|
407
|
+
- breaks convention of reserved namespace via `:`
|
|
408
|
+
|
|
409
|
+
2.1 `_x="abc"`
|
|
410
|
+
- conflicts with `_target="blank"`
|
|
411
|
+
|
|
412
|
+
3. `:.x="abc"`
|
|
413
|
+
+ keeps convention
|
|
414
|
+
+ compatible with `:on*`
|
|
415
|
+
- can be a bit too noisy syntax
|
|
416
|
+
|
|
417
|
+
4. `:_x`
|
|
418
|
+
+ reference to "private"
|
|
419
|
+
- conflicts with `:_target="blank"`
|
|
420
|
+
|
|
421
|
+
5. `:x="this.x=value"`
|
|
422
|
+
+ yepyepyep
|
package/readme.md
CHANGED
|
@@ -126,7 +126,7 @@ Set value of an input, textarea or select. Takes handle of `checked` and `select
|
|
|
126
126
|
|
|
127
127
|
#### `:<prop>="value?"`, `:="props?"`
|
|
128
128
|
|
|
129
|
-
Set any
|
|
129
|
+
Set any attribute value or run effect.
|
|
130
130
|
|
|
131
131
|
```html
|
|
132
132
|
<!-- Single property -->
|
package/sprae.js
CHANGED
|
@@ -367,38 +367,58 @@ signalStruct.isStruct = isStruct;
|
|
|
367
367
|
function signalStruct(values, proto) {
|
|
368
368
|
if (isStruct(values) && !proto)
|
|
369
369
|
return values;
|
|
370
|
-
let state, signals;
|
|
371
370
|
if (isObject(values)) {
|
|
372
|
-
state = Object.create(proto || Object.getPrototypeOf(values)), signals = {};
|
|
373
|
-
let
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
371
|
+
const state = Object.create(proto || Object.getPrototypeOf(values)), signals = {}, descs = Object.getOwnPropertyDescriptors(values);
|
|
372
|
+
for (let key in descs) {
|
|
373
|
+
let desc = descs[key];
|
|
374
|
+
if (desc.get) {
|
|
375
|
+
let s2 = signals[key] = w(desc.get.bind(state));
|
|
376
|
+
Object.defineProperty(state, key, {
|
|
377
|
+
get() {
|
|
378
|
+
return s2.value;
|
|
379
|
+
},
|
|
380
|
+
set: desc.set?.bind(state),
|
|
381
|
+
configurable: false,
|
|
382
|
+
enumerable: true
|
|
383
|
+
});
|
|
384
|
+
} else {
|
|
385
|
+
let value = desc.value;
|
|
386
|
+
let isObservable = observable(value), s2 = signals[key] = isSignal(value) ? value : u(
|
|
387
|
+
isObservable ? void 0 : isObject(value) ? Object.seal(signalStruct(value)) : Array.isArray(value) ? signalStruct(value) : value
|
|
388
|
+
);
|
|
389
|
+
if (isObservable)
|
|
390
|
+
sube_default(value, (v2) => s2.value = v2);
|
|
391
|
+
Object.defineProperty(state, key, {
|
|
392
|
+
get() {
|
|
393
|
+
return s2.value;
|
|
394
|
+
},
|
|
395
|
+
set(v2) {
|
|
396
|
+
if (isObject(v2)) {
|
|
397
|
+
if (isObject(s2.value))
|
|
398
|
+
try {
|
|
399
|
+
Object.assign(s2.value, v2);
|
|
400
|
+
return;
|
|
401
|
+
} catch (e2) {
|
|
402
|
+
}
|
|
403
|
+
s2.value = Object.seal(signalStruct(v2));
|
|
404
|
+
} else if (Array.isArray(v2))
|
|
405
|
+
s2.value = signalStruct(v2);
|
|
406
|
+
else
|
|
407
|
+
s2.value = v2;
|
|
408
|
+
},
|
|
409
|
+
enumerable: true,
|
|
410
|
+
configurable: false
|
|
411
|
+
});
|
|
412
|
+
}
|
|
413
|
+
}
|
|
380
414
|
Object.defineProperty(state, _struct, { configurable: false, enumerable: false, value: true });
|
|
381
415
|
return state;
|
|
382
416
|
}
|
|
383
|
-
if (Array.isArray(values)) {
|
|
417
|
+
if (Array.isArray(values) && !isStruct(values[0])) {
|
|
384
418
|
return values.map((v2) => signalStruct(v2));
|
|
385
419
|
}
|
|
386
420
|
return values;
|
|
387
421
|
}
|
|
388
|
-
function defineSignal(state, key, value) {
|
|
389
|
-
let isObservable, s2 = isSignal(value) ? value : isObject(value) || Array.isArray(value) ? u(signalStruct(value)) : u((isObservable = observable(value)) ? void 0 : value);
|
|
390
|
-
if (isObservable)
|
|
391
|
-
sube_default(value, (v2) => s2.value = v2);
|
|
392
|
-
Object.defineProperty(state, key, {
|
|
393
|
-
get() {
|
|
394
|
-
return s2.value;
|
|
395
|
-
},
|
|
396
|
-
set: !isSignal(value) && isObject(value) ? (v2) => v2 ? Object.assign(s2.value, v2) : s2.value = signalStruct(v2) : (v2) => s2.value = signalStruct(v2),
|
|
397
|
-
enumerable: true,
|
|
398
|
-
configurable: false
|
|
399
|
-
});
|
|
400
|
-
return s2;
|
|
401
|
-
}
|
|
402
422
|
function isObject(v2) {
|
|
403
423
|
return v2 && v2.constructor === Object;
|
|
404
424
|
}
|
|
@@ -690,19 +710,19 @@ directives["aria"] = (el, expr) => {
|
|
|
690
710
|
};
|
|
691
711
|
var evaluatorMemo = {};
|
|
692
712
|
function parseExpr(el, expression, dir) {
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
713
|
+
let evaluate = evaluatorMemo[expression];
|
|
714
|
+
if (!evaluate) {
|
|
715
|
+
let rightSideSafeExpression = /^[\n\s]*if.*\(.*\)/.test(expression) || /^(let|const)\s/.test(expression) ? `(() => { ${expression} })()` : expression;
|
|
716
|
+
try {
|
|
717
|
+
evaluate = evaluatorMemo[expression] = new Function(`__scope`, `with (__scope) { return ${rightSideSafeExpression} };`);
|
|
718
|
+
} catch (e2) {
|
|
719
|
+
return exprError(e2, el, expression, dir);
|
|
720
|
+
}
|
|
701
721
|
}
|
|
702
|
-
return
|
|
722
|
+
return (state) => {
|
|
703
723
|
let result;
|
|
704
724
|
try {
|
|
705
|
-
result = evaluate(state);
|
|
725
|
+
result = evaluate.call(el, state);
|
|
706
726
|
} catch (e2) {
|
|
707
727
|
return exprError(e2, el, expression, dir);
|
|
708
728
|
}
|
package/sprae.min.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
function t(){throw new Error("Cycle detected")}function e(){if(n>1)n--;else{for(var t,e=!1;void 0!==r;){var i=r;for(r=void 0,o++;void 0!==i;){var s=i.o;if(i.o=void 0,i.f&=-3,!(8&i.f)&&u(i))try{i.c()}catch(i){e||(t=i,e=!0)}i=s}}if(o=0,n--,e)throw t}}var i=void 0,r=void 0,n=0,o=0,s=0;function f(t){if(void 0!==i){var e=t.n;if(void 0===e||e.t!==i)return i.s=e={i:0,S:t,p:void 0,n:i.s,t:i,e:void 0,x:void 0,r:e},t.n=e,32&i.f&&t.S(e),e;if(-1===e.i)return e.i=0,void 0!==e.p&&(e.p.n=e.n,void 0!==e.n&&(e.n.p=e.p),e.p=void 0,e.n=i.s,i.s.p=e,i.s=e),e}}function l(t){this.v=t,this.i=0,this.n=void 0,this.t=void 0}function a(t){return new l(t)}function u(t){for(var e=t.s;void 0!==e;e=e.n)if(e.S.i!==e.i||!e.S.h()||e.S.i!==e.i)return!0;return!1}function h(t){for(var e=t.s;void 0!==e;e=e.n){var i=e.S.n;void 0!==i&&(e.r=i),e.S.n=e,e.i=-1}}function c(t){for(var e=t.s,i=void 0;void 0!==e;){var r=e.n;-1===e.i?(e.S.U(e),e.n=void 0):(void 0!==i&&(i.p=e),e.p=void 0,e.n=i,i=e),e.S.n=e.r,void 0!==e.r&&(e.r=void 0),e=r}t.s=i}function v(t){l.call(this,void 0),this.x=t,this.s=void 0,this.g=s-1,this.f=4}function p(t){var r=t.u;if(t.u=void 0,"function"==typeof r){n++;var o=i;i=void 0;try{r()}catch(e){throw t.f&=-2,t.f|=8,d(t),e}finally{i=o,e()}}}function d(t){for(var e=t.s;void 0!==e;e=e.n)e.S.U(e);t.x=void 0,t.s=void 0,p(t)}function y(t){if(i!==this)throw new Error("Out-of-order effect");c(this),i=t,this.f&=-2,8&this.f&&d(this),e()}function b(t){this.x=t,this.u=void 0,this.s=void 0,this.o=void 0,this.f=32}function m(t){var e=new b(t);return e.c(),e.d.bind(e)}l.prototype.h=function(){return!0},l.prototype.S=function(t){this.t!==t&&void 0===t.e&&(t.x=this.t,void 0!==this.t&&(this.t.e=t),this.t=t)},l.prototype.U=function(t){var e=t.e,i=t.x;void 0!==e&&(e.x=i,t.e=void 0),void 0!==i&&(i.e=e,t.x=void 0),t===this.t&&(this.t=i)},l.prototype.subscribe=function(t){var e=this;return m((function(){var i=e.value,r=32&this.f;this.f&=-33;try{t(i)}finally{this.f|=r}}))},l.prototype.valueOf=function(){return this.value},l.prototype.toString=function(){return this.value+""},l.prototype.peek=function(){return this.v},Object.defineProperty(l.prototype,"value",{get:function(){var t=f(this);return void 0!==t&&(t.i=this.i),this.v},set:function(i){if(i!==this.v){o>100&&t(),this.v=i,this.i++,s++,n++;try{for(var r=this.t;void 0!==r;r=r.x)r.t.N()}finally{e()}}}}),(v.prototype=new l).h=function(){if(this.f&=-3,1&this.f)return!1;if(32==(36&this.f))return!0;if(this.f&=-5,this.g===s)return!0;if(this.g=s,this.f|=1,this.i>0&&!u(this))return this.f&=-2,!0;var t=i;try{h(this),i=this;var e=this.x();(16&this.f||this.v!==e||0===this.i)&&(this.v=e,this.f&=-17,this.i++)}catch(t){this.v=t,this.f|=16,this.i++}return i=t,c(this),this.f&=-2,!0},v.prototype.S=function(t){if(void 0===this.t){this.f|=36;for(var e=this.s;void 0!==e;e=e.n)e.S.S(e)}l.prototype.S.call(this,t)},v.prototype.U=function(t){if(l.prototype.U.call(this,t),void 0===this.t){this.f&=-33;for(var e=this.s;void 0!==e;e=e.n)e.S.U(e)}},v.prototype.N=function(){if(!(2&this.f)){this.f|=6;for(var t=this.t;void 0!==t;t=t.x)t.t.N()}},v.prototype.peek=function(){if(this.h()||t(),16&this.f)throw this.v;return this.v},Object.defineProperty(v.prototype,"value",{get:function(){1&this.f&&t();var e=f(this);if(this.h(),void 0!==e&&(e.i=this.i),16&this.f)throw this.v;return this.v}}),b.prototype.c=function(){var t=this.S();try{8&this.f||void 0===this.x||(this.u=this.x())}finally{t()}},b.prototype.S=function(){1&this.f&&t(),this.f|=1,this.f&=-9,p(this),h(this),n++;var e=i;return i=this,y.bind(this,e)},b.prototype.N=function(){2&this.f||(this.f|=2,this.o=r,r=this)},b.prototype.d=function(){this.f|=8,1&this.f||d(this)},Symbol.observable||=Symbol("observable");var g=new FinalizationRegistry((t=>t.call?.())),S=t=>t&&t.peek,x=t=>t&&t[w],w=Symbol("signal-struct");function A(t,e){if(x(t)&&!e)return t;let i,r;if(j(t)){i=Object.create(e||Object.getPrototypeOf(t)),r={};let n=Object.getOwnPropertyDescriptors(t);if(x(t))for(let t in n)Object.defineProperty(i,t,n[t]);else for(let t in n)r[t]=O(i,t,n[t].get?new v(n[t].get.bind(i)):n[t].value);return Object.defineProperty(i,w,{configurable:!1,enumerable:!1,value:!0}),i}return Array.isArray(t)?t.map((t=>A(t))):t}function O(t,e,i){let r,n=S(i)?i:j(i)||Array.isArray(i)?a(A(i)):a((r=(o=i)&&!!(o[Symbol.observable]||o[Symbol.asyncIterator]||o.call&&o.set||o.subscribe||o.then))?void 0:i);var o,s,f,l,u,h,c;return r&&(f=t=>n.value=t,(s=i)&&(c=(s[Symbol.observable]?.()||s).subscribe?.(f,l,undefined),h=c&&(()=>c.unsubscribe?.())||s.set&&s.call?.(u,f)||(s.then?.((t=>{!u&&f(t)}),l)||(async t=>{try{for await(t of s){if(u)return;f(t)}}catch(t){}})())&&(t=>u=1),g.register(s,h))),Object.defineProperty(t,e,{get:()=>n.value,set:!S(i)&&j(i)?t=>t?Object.assign(n.value,t):n.value=A(t):t=>n.value=A(t),enumerable:!0,configurable:!1}),n}function j(t){return t&&t.constructor===Object}A.isStruct=x;var N=(t,e,i,r=null)=>{let n,o,s,f=0,l=i.length,a=e.length,{remove:u,same:h,insert:c,replace:v}=N;for(;f<l&&f<a&&h(e[f],i[f]);)f++;for(;f<l&&f<a&&h(i[l-1],e[a-1]);)r=i[(--a,--l)];if(f==a)for(;f<l;)c(r,i[f++],t);else{for(n=e[f];f<l;)s=i[f++],o=n?n.nextSibling:r,h(n,s)?n=o:f<l&&h(i[f],o)?(v(n,s,t),n=o):c(n,s,t);for(;!h(n,r);)o=n.nextSibling,u(n,t),n=o}return i};N.same=(t,e)=>t==e,N.replace=(t,e,i)=>i.replaceChild(e,t),N.insert=(t,e,i)=>i.insertBefore(e,t),N.remove=(t,e)=>e.removeChild(t);var E=N,W={},k={},$={},P={},C=(t,e,i,r)=>{let n,o=r.startsWith("on")&&r.slice(2),s=R(t,e,":"+r);if(s)return o?e=>{n&&_(t,o,n),n=s(e),n&&D(t,o,n)}:e=>U(t,r,s(e))},U=(t,e,i)=>{null==i||!1===i?t.removeAttribute(e):t.setAttribute(e,!0===i?"":"number"==typeof i||"string"==typeof i?i:"")};P[""]=(t,e)=>{let i=R(t,e,":");if(i)return e=>{let r=i(e);for(let e in r)U(t,I(e),r[e])}};var B=Symbol(":each"),L=Symbol(":ref");P.ref=(t,e,i)=>{t.hasAttribute(":each")?t[L]=e:i[e]=t},P.with=(t,e,i)=>{X(t,A(R(t,e,"with")(i),i))},P.if=(t,e)=>{let i=document.createTextNode(""),r=[R(t,e,":if")],n=[t],o=t;for(;(o=t.nextElementSibling)&&o.hasAttribute(":else");)o.removeAttribute(":else"),(e=o.getAttribute(":if"))?(o.removeAttribute(":if"),o.remove(),n.push(o),r.push(R(t,e,":else :if"))):(o.remove(),n.push(o),r.push((()=>1)));return t.replaceWith(o=i),t=>{let e=r.findIndex((e=>e(t)));n[e]!=o&&((o[B]||o).replaceWith(o=n[e]||i),X(o,t))}},P.each=(t,e)=>{let i=function(t){let e=/,([^,\}\]]*)(?:,([^,\}\]]*))?$/,i=t.match(/([\s\S]*?)\s+(?:in|of)\s+([\s\S]*)/);if(!i)return;let r={};r.items=i[2].trim();let n=i[1].replace(/^\s*\(|\)\s*$/g,"").trim(),o=n.match(e);return o?(r.item=n.replace(e,"").trim(),r.index=o[1].trim()):r.item=n,r}(e);if(!i)return F(new Error,t,e);const r=t[B]=document.createTextNode("");t.replaceWith(r);const n=R(t,i.items,":each"),o=new WeakMap,s=new WeakMap;let f=[];return l=>{let a=n(l);a?"number"==typeof a?a=Array.from({length:a},((t,e)=>[e,e+1])):Array.isArray(a)?a=a.map(((t,e)=>[e+1,t])):"object"==typeof a?a=Object.entries(a):F(Error("Bad list value"),t,e,":each"):a=[];let u=[],h=[];for(let[e,r]of a){let n=null===(c=r)?k:void 0===c?$:"number"==typeof c||c instanceof Number?W[c]||(W[c]=new Number(c)):"string"==typeof c||c instanceof String?W[c]||(W[c]=new String(c)):"boolean"==typeof c||c instanceof Boolean?W[c]||(W[c]=new Boolean(c)):c,f=s.get(n);if(f||(f=t.cloneNode(!0),s.set(n,f)),u.push(f),!o.has(n)){let s=Object.create(l);s[i.item]=r,i.index&&(s[i.index]=e),t[L]&&(s[t[L]]=f),o.set(n,s)}h.push(o.get(n))}var c;E(r.parentNode,f,u,r),f=u;for(let t=0;t<u.length;t++)X(u[t],h[t])}},P.id=(t,e)=>{let i=R(t,e,":id");return e=>{return r=i(e),t.id=r||0===r?r:"";var r}},P.class=(t,e)=>{let i=R(t,e,":class"),r=t.className;return e=>{let n=i(e);t.className=r+typeof n=="string"?n:(Array.isArray(n)?n:Object.entries(n).map((([t,e])=>e?t:""))).filter(Boolean).join(" ")}},P.style=(t,e)=>{let i=R(t,e,":style"),r=t.getAttribute("style")||"";return r.endsWith(";")||(r+="; "),e=>{let n=i(e);if("string"==typeof n)t.setAttribute("style",r+n);else for(let e in n)t.style[e]=n[e]}},P.text=(t,e)=>{let i=R(t,e,":text");return e=>{let r=i(e);t.textContent=null==r?"":r}},P.value=(t,e)=>{let i,r,n=R(t,e,":value"),o="text"===t.type||""===t.type?e=>t.setAttribute("value",t.value=null==e?"":e):"TEXTAREA"===t.tagName||"text"===t.type||""===t.type?e=>(i=t.selectionStart,r=t.selectionEnd,t.setAttribute("value",t.value=null==e?"":e),i&&t.setSelectionRange(i,r)):"checkbox"===t.type?e=>(t.value=e?"on":"",U(t,"checked",e)):"select-one"===t.type?e=>{for(let e in t.options)e.removeAttribute("selected");t.value=e,t.selectedOptions[0]?.setAttribute("selected","")}:e=>t.value=e;return t=>o(n(t))};var T=Symbol("stop");P.on=(t,e)=>{let i=R(t,e,":on"),r={};return e=>{for(let e in r)_(t,e,r[e]);r=i(e);for(let e in r)D(t,e,r[e])}};var D=(t,e,i)=>{if(e.indexOf("..")<0)t.addEventListener(e,i);else{const r=e.split("..").map((t=>t.startsWith("on")?t.slice(2):t)),n=(e,o=0)=>{let s=f=>{t.removeEventListener(r[o],s),"function"!=typeof(e=e.call(t,f))&&(e=()=>{}),++o<r.length?n(e,o):i[T]||n(i)};t.addEventListener(r[o],s)};n(i)}},_=(t,e,i)=>{e.indexOf("..")>=0&&(i[T]=!0),t.removeEventListener(e,i)};P.data=(t,e)=>{let i=R(t,e,":data");return e=>{let r=i(e);for(let e in r)t.dataset[e]=r[e]}},P.aria=(t,e)=>{let i=R(t,e,":aria");return e=>(e=>{for(let i in e)U(t,"aria-"+I(i),null==e[i]?null:e[i]+"")})(i(e))};var M={};function R(t,e,i){if(M[e])return M[e];let r,n=/^[\n\s]*if.*\(.*\)/.test(e)||/^(let|const)\s/.test(e)?`(() => { ${e} })()`:e;try{r=new Function("__scope",`with (__scope) { return ${n} };`).bind(t)}catch(r){return F(r,t,e,i)}return M[e]=n=>{let o;try{o=r(n)}catch(r){return F(r,t,e,i)}return o}}function F(t,e,i,r){Object.assign(t,{element:e,expression:i}),console.warn(`∴ ${t.message}\n\n${r}=${i?`"${i}"\n\n`:""}`,e),setTimeout((()=>{throw t}),0)}function I(t){return t.replace(/[A-Z\u00C0-\u00D6\u00D8-\u00DE]/g,(t=>"-"+t.toLowerCase()))}var z=new WeakMap;function X(t,e){if(!t.children)return;if(z.has(t))return z.get(t);const i=A(e||{}),r=[],n=(t,e=t.parentNode)=>{if(t.attributes)for(let n=0;n<t.attributes.length;){let o=t.attributes[n];if(":"!==o.name[0]){n++;continue}t.removeAttribute(o.name);let s=o.value;if(!s)continue;let f=o.name.slice(1).split(":");for(let n of f){let o=P[n]||C;if(r.push(o(t,s,i,n)||(()=>{})),z.has(t)||t.parentNode!==e)return!1}}for(let e,i=0;e=t.children[i];i++)!1===n(e,t)&&i--};n(t);for(let t of r)m((()=>t(i)));return Object.seal(i),z.set(t,i),i}var Z=X;export{Z as default};
|
|
1
|
+
function t(){throw new Error("Cycle detected")}function e(){if(n>1)n--;else{for(var t,e=!1;void 0!==r;){var i=r;for(r=void 0,o++;void 0!==i;){var s=i.o;if(i.o=void 0,i.f&=-3,!(8&i.f)&&f(i))try{i.c()}catch(i){e||(t=i,e=!0)}i=s}}if(o=0,n--,e)throw t}}var i=void 0,r=void 0,n=0,o=0,s=0;function l(t){if(void 0!==i){var e=t.n;if(void 0===e||e.t!==i)return i.s=e={i:0,S:t,p:void 0,n:i.s,t:i,e:void 0,x:void 0,r:e},t.n=e,32&i.f&&t.S(e),e;if(-1===e.i)return e.i=0,void 0!==e.p&&(e.p.n=e.n,void 0!==e.n&&(e.n.p=e.p),e.p=void 0,e.n=i.s,i.s.p=e,i.s=e),e}}function a(t){this.v=t,this.i=0,this.n=void 0,this.t=void 0}function f(t){for(var e=t.s;void 0!==e;e=e.n)if(e.S.i!==e.i||!e.S.h()||e.S.i!==e.i)return!0;return!1}function u(t){for(var e=t.s;void 0!==e;e=e.n){var i=e.S.n;void 0!==i&&(e.r=i),e.S.n=e,e.i=-1}}function h(t){for(var e=t.s,i=void 0;void 0!==e;){var r=e.n;-1===e.i?(e.S.U(e),e.n=void 0):(void 0!==i&&(i.p=e),e.p=void 0,e.n=i,i=e),e.S.n=e.r,void 0!==e.r&&(e.r=void 0),e=r}t.s=i}function c(t){a.call(this,void 0),this.x=t,this.s=void 0,this.g=s-1,this.f=4}function v(t){var r=t.u;if(t.u=void 0,"function"==typeof r){n++;var o=i;i=void 0;try{r()}catch(e){throw t.f&=-2,t.f|=8,p(t),e}finally{i=o,e()}}}function p(t){for(var e=t.s;void 0!==e;e=e.n)e.S.U(e);t.x=void 0,t.s=void 0,v(t)}function d(t){if(i!==this)throw new Error("Out-of-order effect");h(this),i=t,this.f&=-2,8&this.f&&p(this),e()}function y(t){this.x=t,this.u=void 0,this.s=void 0,this.o=void 0,this.f=32}function b(t){var e=new y(t);return e.c(),e.d.bind(e)}a.prototype.h=function(){return!0},a.prototype.S=function(t){this.t!==t&&void 0===t.e&&(t.x=this.t,void 0!==this.t&&(this.t.e=t),this.t=t)},a.prototype.U=function(t){var e=t.e,i=t.x;void 0!==e&&(e.x=i,t.e=void 0),void 0!==i&&(i.e=e,t.x=void 0),t===this.t&&(this.t=i)},a.prototype.subscribe=function(t){var e=this;return b((function(){var i=e.value,r=32&this.f;this.f&=-33;try{t(i)}finally{this.f|=r}}))},a.prototype.valueOf=function(){return this.value},a.prototype.toString=function(){return this.value+""},a.prototype.peek=function(){return this.v},Object.defineProperty(a.prototype,"value",{get:function(){var t=l(this);return void 0!==t&&(t.i=this.i),this.v},set:function(i){if(i!==this.v){o>100&&t(),this.v=i,this.i++,s++,n++;try{for(var r=this.t;void 0!==r;r=r.x)r.t.N()}finally{e()}}}}),(c.prototype=new a).h=function(){if(this.f&=-3,1&this.f)return!1;if(32==(36&this.f))return!0;if(this.f&=-5,this.g===s)return!0;if(this.g=s,this.f|=1,this.i>0&&!f(this))return this.f&=-2,!0;var t=i;try{u(this),i=this;var e=this.x();(16&this.f||this.v!==e||0===this.i)&&(this.v=e,this.f&=-17,this.i++)}catch(t){this.v=t,this.f|=16,this.i++}return i=t,h(this),this.f&=-2,!0},c.prototype.S=function(t){if(void 0===this.t){this.f|=36;for(var e=this.s;void 0!==e;e=e.n)e.S.S(e)}a.prototype.S.call(this,t)},c.prototype.U=function(t){if(a.prototype.U.call(this,t),void 0===this.t){this.f&=-33;for(var e=this.s;void 0!==e;e=e.n)e.S.U(e)}},c.prototype.N=function(){if(!(2&this.f)){this.f|=6;for(var t=this.t;void 0!==t;t=t.x)t.t.N()}},c.prototype.peek=function(){if(this.h()||t(),16&this.f)throw this.v;return this.v},Object.defineProperty(c.prototype,"value",{get:function(){1&this.f&&t();var e=l(this);if(this.h(),void 0!==e&&(e.i=this.i),16&this.f)throw this.v;return this.v}}),y.prototype.c=function(){var t=this.S();try{8&this.f||void 0===this.x||(this.u=this.x())}finally{t()}},y.prototype.S=function(){1&this.f&&t(),this.f|=1,this.f&=-9,v(this),u(this),n++;var e=i;return i=this,d.bind(this,e)},y.prototype.N=function(){2&this.f||(this.f|=2,this.o=r,r=this)},y.prototype.d=function(){this.f|=8,1&this.f||p(this)},Symbol.observable||=Symbol("observable");var m=new FinalizationRegistry((t=>t.call?.())),g=(t,e,i,r,n,o)=>{return t&&(s=(t[Symbol.observable]?.()||t).subscribe?.(e,i,r),o=s&&(()=>s.unsubscribe?.())||t.set&&t.call?.(n,e)||(t.then?.((t=>(!n&&e(t),r?.())),i)||(async o=>{try{for await(o of t){if(n)return;e(o)}r?.()}catch(t){i?.(t)}})())&&(t=>n=1),m.register(t,o),o);var s},S=t=>t&&t[x],x=Symbol("signal-struct");function w(t,e){if(S(t)&&!e)return t;if(A(t)){const n=Object.create(e||Object.getPrototypeOf(t)),o={},s=Object.getOwnPropertyDescriptors(t);for(let t in s){let e=s[t];if(e.get){let i=o[t]=new c(e.get.bind(n));Object.defineProperty(n,t,{get:()=>i.value,set:e.set?.bind(n),configurable:!1,enumerable:!0})}else{let s=e.value,l=(r=s)&&!!(r[Symbol.observable]||r[Symbol.asyncIterator]||r.call&&r.set||r.subscribe||r.then),f=o[t]=(i=s)&&i.peek?s:new a(l?void 0:A(s)?Object.seal(w(s)):Array.isArray(s)?w(s):s);l&&g(s,(t=>f.value=t)),Object.defineProperty(n,t,{get:()=>f.value,set(t){if(A(t)){if(A(f.value))try{return void Object.assign(f.value,t)}catch(t){}f.value=Object.seal(w(t))}else Array.isArray(t)?f.value=w(t):f.value=t},enumerable:!0,configurable:!1})}}return Object.defineProperty(n,x,{configurable:!1,enumerable:!1,value:!0}),n}var i,r;return Array.isArray(t)&&!S(t[0])?t.map((t=>w(t))):t}function A(t){return t&&t.constructor===Object}w.isStruct=S;var O=(t,e,i,r=null)=>{let n,o,s,l=0,a=i.length,f=e.length,{remove:u,same:h,insert:c,replace:v}=O;for(;l<a&&l<f&&h(e[l],i[l]);)l++;for(;l<a&&l<f&&h(i[a-1],e[f-1]);)r=i[(--f,--a)];if(l==f)for(;l<a;)c(r,i[l++],t);else{for(n=e[l];l<a;)s=i[l++],o=n?n.nextSibling:r,h(n,s)?n=o:l<a&&h(i[l],o)?(v(n,s,t),n=o):c(n,s,t);for(;!h(n,r);)o=n.nextSibling,u(n,t),n=o}return i};O.same=(t,e)=>t==e,O.replace=(t,e,i)=>i.replaceChild(e,t),O.insert=(t,e,i)=>i.insertBefore(e,t),O.remove=(t,e)=>e.removeChild(t);var j=O,N={},E={},W={},k={},$=(t,e,i,r)=>{let n,o=r.startsWith("on")&&r.slice(2),s=_(t,e,":"+r);if(s)return o?e=>{n&&T(t,o,n),n=s(e),n&&L(t,o,n)}:e=>P(t,r,s(e))},P=(t,e,i)=>{null==i||!1===i?t.removeAttribute(e):t.setAttribute(e,!0===i?"":"number"==typeof i||"string"==typeof i?i:"")};k[""]=(t,e)=>{let i=_(t,e,":");if(i)return e=>{let r=i(e);for(let e in r)P(t,R(e),r[e])}};var C=Symbol(":each"),U=Symbol(":ref");k.ref=(t,e,i)=>{t.hasAttribute(":each")?t[U]=e:i[e]=t},k.with=(t,e,i)=>{I(t,w(_(t,e,"with")(i),i))},k.if=(t,e)=>{let i=document.createTextNode(""),r=[_(t,e,":if")],n=[t],o=t;for(;(o=t.nextElementSibling)&&o.hasAttribute(":else");)o.removeAttribute(":else"),(e=o.getAttribute(":if"))?(o.removeAttribute(":if"),o.remove(),n.push(o),r.push(_(t,e,":else :if"))):(o.remove(),n.push(o),r.push((()=>1)));return t.replaceWith(o=i),t=>{let e=r.findIndex((e=>e(t)));n[e]!=o&&((o[C]||o).replaceWith(o=n[e]||i),I(o,t))}},k.each=(t,e)=>{let i=function(t){let e=/,([^,\}\]]*)(?:,([^,\}\]]*))?$/,i=t.match(/([\s\S]*?)\s+(?:in|of)\s+([\s\S]*)/);if(!i)return;let r={};r.items=i[2].trim();let n=i[1].replace(/^\s*\(|\)\s*$/g,"").trim(),o=n.match(e);return o?(r.item=n.replace(e,"").trim(),r.index=o[1].trim()):r.item=n,r}(e);if(!i)return M(new Error,t,e);const r=t[C]=document.createTextNode("");t.replaceWith(r);const n=_(t,i.items,":each"),o=new WeakMap,s=new WeakMap;let l=[];return a=>{let f=n(a);f?"number"==typeof f?f=Array.from({length:f},((t,e)=>[e,e+1])):Array.isArray(f)?f=f.map(((t,e)=>[e+1,t])):"object"==typeof f?f=Object.entries(f):M(Error("Bad list value"),t,e,":each"):f=[];let u=[],h=[];for(let[e,r]of f){let n=null===(c=r)?E:void 0===c?W:"number"==typeof c||c instanceof Number?N[c]||(N[c]=new Number(c)):"string"==typeof c||c instanceof String?N[c]||(N[c]=new String(c)):"boolean"==typeof c||c instanceof Boolean?N[c]||(N[c]=new Boolean(c)):c,l=s.get(n);if(l||(l=t.cloneNode(!0),s.set(n,l)),u.push(l),!o.has(n)){let s=Object.create(a);s[i.item]=r,i.index&&(s[i.index]=e),t[U]&&(s[t[U]]=l),o.set(n,s)}h.push(o.get(n))}var c;j(r.parentNode,l,u,r),l=u;for(let t=0;t<u.length;t++)I(u[t],h[t])}},k.id=(t,e)=>{let i=_(t,e,":id");return e=>{return r=i(e),t.id=r||0===r?r:"";var r}},k.class=(t,e)=>{let i=_(t,e,":class"),r=t.className;return e=>{let n=i(e);t.className=r+typeof n=="string"?n:(Array.isArray(n)?n:Object.entries(n).map((([t,e])=>e?t:""))).filter(Boolean).join(" ")}},k.style=(t,e)=>{let i=_(t,e,":style"),r=t.getAttribute("style")||"";return r.endsWith(";")||(r+="; "),e=>{let n=i(e);if("string"==typeof n)t.setAttribute("style",r+n);else for(let e in n)t.style[e]=n[e]}},k.text=(t,e)=>{let i=_(t,e,":text");return e=>{let r=i(e);t.textContent=null==r?"":r}},k.value=(t,e)=>{let i,r,n=_(t,e,":value"),o="text"===t.type||""===t.type?e=>t.setAttribute("value",t.value=null==e?"":e):"TEXTAREA"===t.tagName||"text"===t.type||""===t.type?e=>(i=t.selectionStart,r=t.selectionEnd,t.setAttribute("value",t.value=null==e?"":e),i&&t.setSelectionRange(i,r)):"checkbox"===t.type?e=>(t.value=e?"on":"",P(t,"checked",e)):"select-one"===t.type?e=>{for(let e in t.options)e.removeAttribute("selected");t.value=e,t.selectedOptions[0]?.setAttribute("selected","")}:e=>t.value=e;return t=>o(n(t))};var B=Symbol("stop");k.on=(t,e)=>{let i=_(t,e,":on"),r={};return e=>{for(let e in r)T(t,e,r[e]);r=i(e);for(let e in r)L(t,e,r[e])}};var L=(t,e,i)=>{if(e.indexOf("..")<0)t.addEventListener(e,i);else{const r=e.split("..").map((t=>t.startsWith("on")?t.slice(2):t)),n=(e,o=0)=>{let s=l=>{t.removeEventListener(r[o],s),"function"!=typeof(e=e.call(t,l))&&(e=()=>{}),++o<r.length?n(e,o):i[B]||n(i)};t.addEventListener(r[o],s)};n(i)}},T=(t,e,i)=>{e.indexOf("..")>=0&&(i[B]=!0),t.removeEventListener(e,i)};k.data=(t,e)=>{let i=_(t,e,":data");return e=>{let r=i(e);for(let e in r)t.dataset[e]=r[e]}},k.aria=(t,e)=>{let i=_(t,e,":aria");return e=>(e=>{for(let i in e)P(t,"aria-"+R(i),null==e[i]?null:e[i]+"")})(i(e))};var D={};function _(t,e,i){let r=D[e];if(!r){let n=/^[\n\s]*if.*\(.*\)/.test(e)||/^(let|const)\s/.test(e)?`(() => { ${e} })()`:e;try{r=D[e]=new Function("__scope",`with (__scope) { return ${n} };`)}catch(r){return M(r,t,e,i)}}return n=>{let o;try{o=r.call(t,n)}catch(r){return M(r,t,e,i)}return o}}function M(t,e,i,r){Object.assign(t,{element:e,expression:i}),console.warn(`∴ ${t.message}\n\n${r}=${i?`"${i}"\n\n`:""}`,e),setTimeout((()=>{throw t}),0)}function R(t){return t.replace(/[A-Z\u00C0-\u00D6\u00D8-\u00DE]/g,(t=>"-"+t.toLowerCase()))}var F=new WeakMap;function I(t,e){if(!t.children)return;if(F.has(t))return F.get(t);const i=w(e||{}),r=[],n=(t,e=t.parentNode)=>{if(t.attributes)for(let n=0;n<t.attributes.length;){let o=t.attributes[n];if(":"!==o.name[0]){n++;continue}t.removeAttribute(o.name);let s=o.value;if(!s)continue;let l=o.name.slice(1).split(":");for(let n of l){let o=k[n]||$;if(r.push(o(t,s,i,n)||(()=>{})),F.has(t)||t.parentNode!==e)return!1}}for(let e,i=0;e=t.children[i];i++)!1===n(e,t)&&i--};n(t);for(let t of r)b((()=>t(i)));return Object.seal(i),F.set(t,i),i}var z=I;export{z as default};
|
package/src/directives.js
CHANGED
|
@@ -11,7 +11,6 @@ export const directives = {}
|
|
|
11
11
|
export default (el, expr, values, name) => {
|
|
12
12
|
let evt = name.startsWith('on') && name.slice(2)
|
|
13
13
|
let evaluate = parseExpr(el, expr, ':'+name)
|
|
14
|
-
|
|
15
14
|
let value
|
|
16
15
|
if (evaluate) return evt ? state => {
|
|
17
16
|
value && removeListener(el, evt, value)
|
|
@@ -285,31 +284,32 @@ let evaluatorMemo = {}
|
|
|
285
284
|
// borrowed from alpine: https://github.com/alpinejs/alpine/blob/main/packages/alpinejs/src/evaluator.js#L61
|
|
286
285
|
// it seems to be more robust than subscript
|
|
287
286
|
function parseExpr(el, expression, dir) {
|
|
288
|
-
if (evaluatorMemo[expression]) return evaluatorMemo[expression]
|
|
289
|
-
|
|
290
|
-
// Some expressions that are useful in Alpine are not valid as the right side of an expression.
|
|
291
|
-
// Here we'll detect if the expression isn't valid for an assignement and wrap it in a self-
|
|
292
|
-
// calling function so that we don't throw an error AND a "return" statement can b e used.
|
|
293
|
-
let rightSideSafeExpression = 0
|
|
294
|
-
// Support expressions starting with "if" statements like: "if (...) doSomething()"
|
|
295
|
-
|| /^[\n\s]*if.*\(.*\)/.test(expression)
|
|
296
|
-
// Support expressions starting with "let/const" like: "let foo = 'bar'"
|
|
297
|
-
|| /^(let|const)\s/.test(expression)
|
|
298
|
-
? `(() => { ${expression} })()`
|
|
299
|
-
: expression;
|
|
300
|
-
|
|
301
287
|
// guard static-time eval errors
|
|
302
|
-
let evaluate
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
288
|
+
let evaluate = evaluatorMemo[expression]
|
|
289
|
+
|
|
290
|
+
if (!evaluate) {
|
|
291
|
+
// Some expressions that are useful in Alpine are not valid as the right side of an expression.
|
|
292
|
+
// Here we'll detect if the expression isn't valid for an assignement and wrap it in a self-
|
|
293
|
+
// calling function so that we don't throw an error AND a "return" statement can b e used.
|
|
294
|
+
let rightSideSafeExpression = 0
|
|
295
|
+
// Support expressions starting with "if" statements like: "if (...) doSomething()"
|
|
296
|
+
|| /^[\n\s]*if.*\(.*\)/.test(expression)
|
|
297
|
+
// Support expressions starting with "let/const" like: "let foo = 'bar'"
|
|
298
|
+
|| /^(let|const)\s/.test(expression)
|
|
299
|
+
? `(() => { ${expression} })()`
|
|
300
|
+
: expression;
|
|
301
|
+
|
|
302
|
+
try {
|
|
303
|
+
evaluate = evaluatorMemo[expression] = new Function(`__scope`,`with (__scope) { return ${rightSideSafeExpression} };`)
|
|
304
|
+
} catch ( e ) {
|
|
305
|
+
return exprError(e, el, expression, dir)
|
|
306
|
+
}
|
|
307
307
|
}
|
|
308
308
|
|
|
309
309
|
// guard runtime eval errors
|
|
310
|
-
return
|
|
310
|
+
return (state) => {
|
|
311
311
|
let result
|
|
312
|
-
try { result = evaluate(state) }
|
|
312
|
+
try { result = evaluate.call(el, state) }
|
|
313
313
|
catch (e) { return exprError(e, el, expression, dir) }
|
|
314
314
|
return result
|
|
315
315
|
}
|
package/test/test.js
CHANGED
|
@@ -81,12 +81,26 @@ test('props: base', async () => {
|
|
|
81
81
|
is(el.outerHTML, `<input id="0" for="1" title="2" help="3" type="4" placeholder="5" value="7" a-b="8">`)
|
|
82
82
|
})
|
|
83
83
|
|
|
84
|
+
test('props: sets prop', async () => {
|
|
85
|
+
let el = h`<x :x="this.x=1" :y="this.y='abc'"></x>`
|
|
86
|
+
sprae(el)
|
|
87
|
+
is(el.x, 1)
|
|
88
|
+
is(el.y, 'abc')
|
|
89
|
+
})
|
|
90
|
+
|
|
84
91
|
test('props: multiprop', async () => {
|
|
85
92
|
let el = h`<input :id:name:for="0" />`
|
|
86
93
|
let params = sprae(el)
|
|
87
94
|
is(el.outerHTML, `<input id="0" name="0" for="0">`)
|
|
88
95
|
})
|
|
89
96
|
|
|
97
|
+
// FIXME: this must work without return
|
|
98
|
+
test.todo('props: calculation', async () => {
|
|
99
|
+
let el = h`<x :x="let a = 5; return Array.from({length:a}, (_,i)=>i).join(' ')"></x>`
|
|
100
|
+
sprae(el);
|
|
101
|
+
is(el.outerHTML, `<x x="01234"></x>`)
|
|
102
|
+
})
|
|
103
|
+
|
|
90
104
|
test('data: base', async () => {
|
|
91
105
|
let el = h`<input :data="{a:1, fooBar:2}"/>`
|
|
92
106
|
let params = sprae(el)
|
|
@@ -352,6 +366,14 @@ test('each: condition within loop', async () => {
|
|
|
352
366
|
is(el.innerHTML, '')
|
|
353
367
|
})
|
|
354
368
|
|
|
369
|
+
test('each: next items have own "this", not single one', async () => {
|
|
370
|
+
// FIXME: let el = h`<x :each="x in 3"></x>`
|
|
371
|
+
let el = h`<div><x :each="x in 3" :data="{x}" :x="log.push(x, this.dataset.x)"></x></div>`
|
|
372
|
+
let log = []
|
|
373
|
+
let state = sprae(el, {log})
|
|
374
|
+
is(state.log, [1,'1',2,'2',3,'3'])
|
|
375
|
+
})
|
|
376
|
+
|
|
355
377
|
test('on: base', () => {
|
|
356
378
|
let el = h`<div :on="{click(e){log.push('click')},x}"></div>`
|
|
357
379
|
let log = signal([])
|