sprae 2.1.1 → 2.1.2
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/examples/todomvc.html +1 -1
- package/package.json +1 -1
- package/readme.md +4 -0
- package/sprae.js +11 -9
- package/sprae.min.js +1 -1
- package/src/core.js +7 -4
- package/src/directives.js +5 -4
- package/test/test.js +19 -0
package/examples/todomvc.html
CHANGED
package/package.json
CHANGED
package/readme.md
CHANGED
|
@@ -230,6 +230,10 @@ Update happens when any value changes:
|
|
|
230
230
|
```
|
|
231
231
|
-->
|
|
232
232
|
|
|
233
|
+
## Examples
|
|
234
|
+
|
|
235
|
+
* TODO MVC: [demo](https://dy.github.io/sprae/examples/todomvc), [code](https://github.com/dy/sprae/blob/main/examples/todomvc.html)
|
|
236
|
+
|
|
233
237
|
## Justification
|
|
234
238
|
|
|
235
239
|
* [Template-parts](https://github.com/dy/template-parts) / [templize](https://github.com/dy/templize) is progressive, but is stuck with native HTML quirks ([parsing table](https://github.com/github/template-parts/issues/24), [svg attributes](https://github.com/github/template-parts/issues/25), [liquid syntax](https://shopify.github.io/liquid/tags/template/#raw) conflict etc). Also ergonomics of `attr="{{}}"` is inferior to `:attr=""` since it creates flash of uninitialized values.
|
package/sprae.js
CHANGED
|
@@ -527,7 +527,7 @@ directives[":if"] = (el2, expr, state) => {
|
|
|
527
527
|
el2.replaceWith(cur = holder);
|
|
528
528
|
let idx = w(() => clauses.findIndex((f2) => f2(state)));
|
|
529
529
|
b((i2 = idx.value) => els[i2] != cur && ((cur[_each] || cur).replaceWith(cur = els[i2] || holder), sprae(cur, state)));
|
|
530
|
-
return
|
|
530
|
+
return -els.length;
|
|
531
531
|
};
|
|
532
532
|
directives[":each"] = (tpl, expr, state) => {
|
|
533
533
|
let each = parseForExpression(expr);
|
|
@@ -578,7 +578,7 @@ directives[":each"] = (tpl, expr, state) => {
|
|
|
578
578
|
sprae(newEls[i2], elScopes[i2]);
|
|
579
579
|
}
|
|
580
580
|
});
|
|
581
|
-
return
|
|
581
|
+
return -1;
|
|
582
582
|
};
|
|
583
583
|
function parseForExpression(expression) {
|
|
584
584
|
let forIteratorRE = /,([^,\}\]]*)(?:,([^,\}\]]*))?$/;
|
|
@@ -701,28 +701,30 @@ function sprae(container, values) {
|
|
|
701
701
|
values ||= {};
|
|
702
702
|
const state = SignalStruct(values);
|
|
703
703
|
const init = (el2) => {
|
|
704
|
-
let dir, attr;
|
|
704
|
+
let dir, attr, res;
|
|
705
705
|
if (el2.attributes) {
|
|
706
706
|
for (let name in directives) {
|
|
707
707
|
if (attr = el2.attributes[name]) {
|
|
708
708
|
dir = directives[name];
|
|
709
709
|
el2.removeAttribute(name);
|
|
710
|
-
if (dir(el2, attr.value, state)
|
|
711
|
-
return;
|
|
710
|
+
if ((res = dir(el2, attr.value, state)) <= 0)
|
|
711
|
+
return res;
|
|
712
712
|
}
|
|
713
713
|
}
|
|
714
714
|
for (let i2 = 0; i2 < el2.attributes.length; ) {
|
|
715
715
|
let attr2 = el2.attributes[i2];
|
|
716
716
|
if (attr2.name[0] === ":") {
|
|
717
717
|
el2.removeAttribute(attr2.name);
|
|
718
|
-
if (directives_default(el2, attr2.value, state, attr2.name.slice(1))
|
|
719
|
-
return;
|
|
718
|
+
if ((res = directives_default(el2, attr2.value, state, attr2.name.slice(1))) <= 0)
|
|
719
|
+
return res;
|
|
720
720
|
} else
|
|
721
721
|
i2++;
|
|
722
722
|
}
|
|
723
723
|
}
|
|
724
|
-
for (let child
|
|
725
|
-
init(child);
|
|
724
|
+
for (let i2 = 0, child; child = el2.children[i2]; i2++) {
|
|
725
|
+
res = init(child) || 0;
|
|
726
|
+
i2 += res;
|
|
727
|
+
}
|
|
726
728
|
};
|
|
727
729
|
init(container);
|
|
728
730
|
memo.set(container, state);
|
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)&&l(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 a(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 f(t){this.v=t,this.i=0,this.n=void 0,this.t=void 0}function u(t){return new f(t)}function l(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 v(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){f.call(this,void 0),this.x=t,this.s=void 0,this.g=s-1,this.f=4}function d(t){return new c(t)}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,b(t),e}finally{i=o,e()}}}function b(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");v(this),i=t,this.f&=-2,8&this.f&&b(this),e()}function m(t){this.x=t,this.u=void 0,this.s=void 0,this.o=void 0,this.f=32}function g(t){var e=new m(t);return e.c(),e.d.bind(e)}f.prototype.h=function(){return!0},f.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)},f.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)},f.prototype.subscribe=function(t){var e=this;return g((function(){var i=e.value,r=32&this.f;this.f&=-33;try{t(i)}finally{this.f|=r}}))},f.prototype.valueOf=function(){return this.value},f.prototype.toString=function(){return this.value+""},f.prototype.peek=function(){return this.v},Object.defineProperty(f.prototype,"value",{get:function(){var t=a(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 f).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&&!l(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,v(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)}f.prototype.S.call(this,t)},c.prototype.U=function(t){if(f.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=a(this);if(this.h(),void 0!==e&&(e.i=this.i),16&this.f)throw this.v;return this.v}}),m.prototype.c=function(){var t=this.S();try{8&this.f||void 0===this.x||(this.u=this.x())}finally{t()}},m.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)},m.prototype.N=function(){2&this.f||(this.f|=2,this.o=r,r=this)},m.prototype.d=function(){this.f|=8,1&this.f||b(this)},Symbol.observable||=Symbol("observable");var S=new FinalizationRegistry((t=>t.call?.())),x=t=>t&&t.peek,w=Symbol("signal-struct");function A(t){if((e=t)&&e[w])return t;var e;let i,r;if(j(t)){i={},r={};for(let e in t)r[e]=O(i,e,t[e]);return Object.defineProperty(i,w,{configurable:!1,enumerable:!1,value:!0}),Object.seal(i),i}return Array.isArray(t)?t.map((t=>A(t))):t}function O(t,e,i){let r,n=x(i)?i:j(i)||Array.isArray(i)?u(A(i)):u((r=(o=i)&&!!(o[Symbol.observable]||o[Symbol.asyncIterator]||o.call&&o.set||o.subscribe||o.then))?void 0:i);var o,s,a,f,l,h,v;return r&&(a=t=>n.value=t,(s=i)&&(v=(s[Symbol.observable]?.()||s).subscribe?.(a,f,undefined),h=v&&(()=>v.unsubscribe?.())||s.set&&s.call?.(l,a)||(s.then?.((t=>{!l&&a(t)}),f)||(async t=>{try{for await(t of s){if(l)return;a(t)}}catch(t){}})())&&(t=>l=1),S.register(s,h))),Object.defineProperty(t,e,{get:()=>n.value,set:!x(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}var k=(t,e,i)=>{e.startsWith("on")&&(e=e.toLowerCase()),t[e]!==i&&(t[e]=i),!1===i||null==i?t.removeAttribute(e):"function"!=typeof i&&t.setAttribute($(e),!0===i?"":"number"==typeof i||"string"==typeof i?i:"class"===e?(Array.isArray(i)?i:Object.entries(i).map((([t,e])=>e?t:""))).filter(Boolean).join(" "):"style"===e?Object.entries(i).map((([t,e])=>`${t}: ${e}`)).join(";"):"")},N=document.createElement("div"),$=t=>{N.dataset[t]="";let e=N.attributes[0].name.slice(5);return delete N.dataset[t],e},E=(t,e,i,r=null)=>{let n,o,s,a=0,f=i.length,u=e.length,{remove:l,same:h,insert:v,replace:c}=E;for(;a<f&&a<u&&h(e[a],i[a]);)a++;for(;a<f&&a<u&&h(i[f-1],e[u-1]);)r=i[(--u,--f)];if(a==u)for(;a<f;)v(r,i[a++],t);else{for(n=e[a];a<f;)s=i[a++],o=n?n.nextSibling:r,h(n,s)?n=o:a<f&&h(i[a],o)?(c(n,s,t),n=o):v(n,s,t);for(;!h(n,r);)o=n.nextSibling,l(n,t),n=o}return i};E.same=(t,e)=>t==e,E.replace=(t,e,i)=>i.replaceChild(e,t),E.insert=(t,e,i)=>i.insertBefore(e,t),E.remove=(t,e)=>e.removeChild(t);var U=E,W={},C={},B={},P=(t,e,i,r)=>{let n=I(e,":"+r,i);g((()=>{return e=n(i),k(t,r,e);var e}))},L={},M=Symbol(":each"),T=Symbol(":ref");L[":with"]=(t,i,r)=>{let o=I(i,"with",r);const s=d((()=>Object.assign({},r,o(r))));let a=q(t,s.value);return g(((t=s.value)=>function(t){if(n>0)return t();n++;try{return t()}finally{e()}}((()=>Object.assign(a,t))))),!1},L[":ref"]=(t,e,i)=>t.hasAttribute(":each")?t[T]=e:(q(t,Object.assign(Object.create(i),{[e]:t})),!1),L[":if"]=(t,e,i)=>{let r=document.createTextNode(""),n=[I(e,":if",i)],o=[t],s=t;for(;(s=t.nextElementSibling)&&s.hasAttribute(":else");)s.removeAttribute(":else"),(e=s.getAttribute(":if"))?(s.removeAttribute(":if"),s.remove(),o.push(s),n.push(I(e,":else :if",i))):(s.remove(),o.push(s),n.push((()=>1)));t.replaceWith(s=r);let a=d((()=>n.findIndex((t=>t(i)))));return g(((t=a.value)=>o[t]!=s&&((s[M]||s).replaceWith(s=o[t]||r),q(s,i))))
|
|
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)&&l(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 a(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 f(t){this.v=t,this.i=0,this.n=void 0,this.t=void 0}function u(t){return new f(t)}function l(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 v(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){f.call(this,void 0),this.x=t,this.s=void 0,this.g=s-1,this.f=4}function d(t){return new c(t)}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,b(t),e}finally{i=o,e()}}}function b(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");v(this),i=t,this.f&=-2,8&this.f&&b(this),e()}function m(t){this.x=t,this.u=void 0,this.s=void 0,this.o=void 0,this.f=32}function g(t){var e=new m(t);return e.c(),e.d.bind(e)}f.prototype.h=function(){return!0},f.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)},f.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)},f.prototype.subscribe=function(t){var e=this;return g((function(){var i=e.value,r=32&this.f;this.f&=-33;try{t(i)}finally{this.f|=r}}))},f.prototype.valueOf=function(){return this.value},f.prototype.toString=function(){return this.value+""},f.prototype.peek=function(){return this.v},Object.defineProperty(f.prototype,"value",{get:function(){var t=a(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 f).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&&!l(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,v(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)}f.prototype.S.call(this,t)},c.prototype.U=function(t){if(f.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=a(this);if(this.h(),void 0!==e&&(e.i=this.i),16&this.f)throw this.v;return this.v}}),m.prototype.c=function(){var t=this.S();try{8&this.f||void 0===this.x||(this.u=this.x())}finally{t()}},m.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)},m.prototype.N=function(){2&this.f||(this.f|=2,this.o=r,r=this)},m.prototype.d=function(){this.f|=8,1&this.f||b(this)},Symbol.observable||=Symbol("observable");var S=new FinalizationRegistry((t=>t.call?.())),x=t=>t&&t.peek,w=Symbol("signal-struct");function A(t){if((e=t)&&e[w])return t;var e;let i,r;if(j(t)){i={},r={};for(let e in t)r[e]=O(i,e,t[e]);return Object.defineProperty(i,w,{configurable:!1,enumerable:!1,value:!0}),Object.seal(i),i}return Array.isArray(t)?t.map((t=>A(t))):t}function O(t,e,i){let r,n=x(i)?i:j(i)||Array.isArray(i)?u(A(i)):u((r=(o=i)&&!!(o[Symbol.observable]||o[Symbol.asyncIterator]||o.call&&o.set||o.subscribe||o.then))?void 0:i);var o,s,a,f,l,h,v;return r&&(a=t=>n.value=t,(s=i)&&(v=(s[Symbol.observable]?.()||s).subscribe?.(a,f,undefined),h=v&&(()=>v.unsubscribe?.())||s.set&&s.call?.(l,a)||(s.then?.((t=>{!l&&a(t)}),f)||(async t=>{try{for await(t of s){if(l)return;a(t)}}catch(t){}})())&&(t=>l=1),S.register(s,h))),Object.defineProperty(t,e,{get:()=>n.value,set:!x(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}var k=(t,e,i)=>{e.startsWith("on")&&(e=e.toLowerCase()),t[e]!==i&&(t[e]=i),!1===i||null==i?t.removeAttribute(e):"function"!=typeof i&&t.setAttribute($(e),!0===i?"":"number"==typeof i||"string"==typeof i?i:"class"===e?(Array.isArray(i)?i:Object.entries(i).map((([t,e])=>e?t:""))).filter(Boolean).join(" "):"style"===e?Object.entries(i).map((([t,e])=>`${t}: ${e}`)).join(";"):"")},N=document.createElement("div"),$=t=>{N.dataset[t]="";let e=N.attributes[0].name.slice(5);return delete N.dataset[t],e},E=(t,e,i,r=null)=>{let n,o,s,a=0,f=i.length,u=e.length,{remove:l,same:h,insert:v,replace:c}=E;for(;a<f&&a<u&&h(e[a],i[a]);)a++;for(;a<f&&a<u&&h(i[f-1],e[u-1]);)r=i[(--u,--f)];if(a==u)for(;a<f;)v(r,i[a++],t);else{for(n=e[a];a<f;)s=i[a++],o=n?n.nextSibling:r,h(n,s)?n=o:a<f&&h(i[a],o)?(c(n,s,t),n=o):v(n,s,t);for(;!h(n,r);)o=n.nextSibling,l(n,t),n=o}return i};E.same=(t,e)=>t==e,E.replace=(t,e,i)=>i.replaceChild(e,t),E.insert=(t,e,i)=>i.insertBefore(e,t),E.remove=(t,e)=>e.removeChild(t);var U=E,W={},C={},B={},P=(t,e,i,r)=>{let n=I(e,":"+r,i);g((()=>{return e=n(i),k(t,r,e);var e}))},L={},M=Symbol(":each"),T=Symbol(":ref");L[":with"]=(t,i,r)=>{let o=I(i,"with",r);const s=d((()=>Object.assign({},r,o(r))));let a=q(t,s.value);return g(((t=s.value)=>function(t){if(n>0)return t();n++;try{return t()}finally{e()}}((()=>Object.assign(a,t))))),!1},L[":ref"]=(t,e,i)=>t.hasAttribute(":each")?t[T]=e:(q(t,Object.assign(Object.create(i),{[e]:t})),!1),L[":if"]=(t,e,i)=>{let r=document.createTextNode(""),n=[I(e,":if",i)],o=[t],s=t;for(;(s=t.nextElementSibling)&&s.hasAttribute(":else");)s.removeAttribute(":else"),(e=s.getAttribute(":if"))?(s.removeAttribute(":if"),s.remove(),o.push(s),n.push(I(e,":else :if",i))):(s.remove(),o.push(s),n.push((()=>1)));t.replaceWith(s=r);let a=d((()=>n.findIndex((t=>t(i)))));return g(((t=a.value)=>o[t]!=s&&((s[M]||s).replaceWith(s=o[t]||r),q(s,i)))),-o.length},L[":each"]=(t,e,i)=>{let r=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(!r)return z(new Error,e);const n=I(r.items,":each",i),o=t[M]=document.createTextNode("");t.replaceWith(o);const s=d((()=>{let t=n(i);return t?"number"==typeof t?Array.from({length:t},((t,e)=>[e,e+1])):t.constructor===Object?Object.entries(t):Array.isArray(t)?t.map(((t,e)=>[e+1,t])):void z(Error("Bad list value"),r.items,":each",t):[]})),a=new WeakMap,f=new WeakMap;let u=[];return g(((e=s.value)=>{let n=[],l=[];for(let[o,s]of e){let e=null===(h=s)?C:void 0===h?B:"number"==typeof h||h instanceof Number?W[h]||(W[h]=new Number(h)):"string"==typeof h||h instanceof String?W[h]||(W[h]=new String(h)):"boolean"==typeof h||h instanceof Boolean?W[h]||(W[h]=new Boolean(h)):h,u=f.get(e);if(u||(u=t.cloneNode(!0),f.set(e,u)),n.push(u),!a.has(e)){let n=Object.create(i);n[r.item]=s,r.index&&(n[r.index]=o),t[T]&&(n[t[T]]=u),a.set(e,n)}l.push(a.get(e))}var h;U(o.parentNode,u,n,o),u=n;for(let t=0;t<n.length;t++)q(n[t],l[t])})),-1},L[":id"]=(t,e,i)=>{let r=I(e,":id",i);g((()=>{return e=r(i),t.id=e||0===e?e:"";var e}))},L[":"]=(t,e,i)=>{let r=I(e,":",i);g((()=>(e=>{if(e)for(let i in e)k(t,i,e[i])})(r(i))))},L[":text"]=(t,e,i)=>{let r=I(e,":text",i);g((()=>{return e=r(i),void(t.textContent=null==e?"":e);var e}))},L[":value"]=(t,e,i)=>{let r=I(e,":in",i),[n,o]=(t=>["checkbox"===t.type?()=>t.checked:()=>t.value,"text"===t.type||""===t.type?e=>t.value=null==e?"":e:"checkbox"===t.type?e=>(t.value=e?"on":"",k(t,"checked",e)):"select-one"===t.type?e=>([...t.options].map((t=>t.removeAttribute("selected"))),t.value=e,t.selectedOptions[0]?.setAttribute("selected","")):e=>t.value=e])(t);g((()=>{return e=r(i),k(t,"value",e),void o(e);var e}))},L[":on"]=(t,e,i)=>{let r,n=I(e,":on",i),o=d((()=>n(i)));g(((e=o.value)=>{for(let e in r)t.removeEventListener(e,r[e]);r=e;for(let e in r)t.addEventListener(e,r[e])}))},L[":data"]=(t,e,i)=>{let r=I(e,":data",i);const n=d((()=>r(i)));g(((e=n.value)=>{for(let i in e)t.dataset[i]=e[i]}))},L[":aria"]=(t,e,i)=>{let r=I(e,":aria",i);g((()=>(e=>{for(let i in e)k(t,"aria"+i[0].toUpperCase()+i.slice(1),null==e[i]?null:e[i]+"")})(r(i))))};var F={};function I(t,e,i){if(F[t])return F[t];let r,n=/^[\n\s]*if.*\(.*\)/.test(t)||/^(let|const)\s/.test(t)?`(() => { ${t} })()`:t;try{r=new Function(`let result; with (arguments[0]) { result = (${n}) }; return result;`)}catch(r){return z(r,t,e,i)}return F[t]=n=>{let o;try{o=r(n)}catch(r){return z(r,t,e,i)}return o}}function z(t,e,i,r){Object.assign(t,{expression:e}),console.warn(`∴sprae: ${t.message}\n\n${i}=${e?`"${e}"\n\n`:""}`,r),setTimeout((()=>{throw t}),0)}var R=new WeakMap;function q(t,e){if(!t.children)return;if(R.has(t))return R.get(t);e||={};const i=A(e),r=t=>{let e,n,o;if(t.attributes){for(let r in L)if((n=t.attributes[r])&&(e=L[r],t.removeAttribute(r),(o=e(t,n.value,i))<=0))return o;for(let e=0;e<t.attributes.length;){let r=t.attributes[e];if(":"===r.name[0]){if(t.removeAttribute(r.name),(o=P(t,r.value,i,r.name.slice(1)))<=0)return o}else e++}}for(let e,i=0;e=t.children[i];i++)o=r(e)||0,i+=o};return r(t),R.set(t,i),i}var D=q;export{D as default};
|
package/src/core.js
CHANGED
|
@@ -13,7 +13,7 @@ export default function sprae(container, values) {
|
|
|
13
13
|
|
|
14
14
|
// init directives on element
|
|
15
15
|
const init = (el) => {
|
|
16
|
-
let dir, attr
|
|
16
|
+
let dir, attr, res
|
|
17
17
|
|
|
18
18
|
if (el.attributes) {
|
|
19
19
|
// directives must be initialized in order
|
|
@@ -21,7 +21,7 @@ export default function sprae(container, values) {
|
|
|
21
21
|
if (attr = el.attributes[name]) {
|
|
22
22
|
dir = directives[name]
|
|
23
23
|
el.removeAttribute(name)
|
|
24
|
-
if (dir(el, attr.value, state)
|
|
24
|
+
if ((res = dir(el, attr.value, state)) <= 0) return res
|
|
25
25
|
}
|
|
26
26
|
}
|
|
27
27
|
|
|
@@ -29,13 +29,16 @@ export default function sprae(container, values) {
|
|
|
29
29
|
let attr = el.attributes[i]
|
|
30
30
|
if (attr.name[0]===':') {
|
|
31
31
|
el.removeAttribute(attr.name)
|
|
32
|
-
if (defaultDirective(el, attr.value, state, attr.name.slice(1))
|
|
32
|
+
if ((res = defaultDirective(el, attr.value, state, attr.name.slice(1))) <= 0) return res
|
|
33
33
|
}
|
|
34
34
|
else i++
|
|
35
35
|
}
|
|
36
36
|
}
|
|
37
37
|
|
|
38
|
-
for (let child
|
|
38
|
+
for (let i = 0, child; child = el.children[i]; i++) {
|
|
39
|
+
res = init(child) || 0 // reduce number of removed elements
|
|
40
|
+
i += res
|
|
41
|
+
}
|
|
39
42
|
}
|
|
40
43
|
|
|
41
44
|
init(container)
|
package/src/directives.js
CHANGED
|
@@ -27,7 +27,7 @@ directives[':with'] = (el, expr, rootState) => {
|
|
|
27
27
|
const params = computed(() => Object.assign({}, rootState, evaluate(rootState)))
|
|
28
28
|
let state = sprae(el, params.value)
|
|
29
29
|
effect((values=params.value) => batch(() => Object.assign(state, values)))
|
|
30
|
-
return false
|
|
30
|
+
return false // don't continue attrs init
|
|
31
31
|
}
|
|
32
32
|
|
|
33
33
|
directives[':ref'] = (el, expr, state) => {
|
|
@@ -35,7 +35,7 @@ directives[':ref'] = (el, expr, state) => {
|
|
|
35
35
|
if (el.hasAttribute(':each')) return el[_ref] = expr;
|
|
36
36
|
|
|
37
37
|
sprae(el, Object.assign(Object.create(state), {[expr]: el}))
|
|
38
|
-
return false
|
|
38
|
+
return false // don't continue attrs init
|
|
39
39
|
}
|
|
40
40
|
|
|
41
41
|
directives[':if'] = (el, expr, state) => {
|
|
@@ -62,7 +62,8 @@ directives[':if'] = (el, expr, state) => {
|
|
|
62
62
|
// NOTE: it lazily initializes elements on insertion, it's safe to sprae multiple times
|
|
63
63
|
effect((i=idx.value) => (els[i] != cur && ((cur[_each]||cur).replaceWith(cur = els[i] || holder), sprae(cur, state))))
|
|
64
64
|
|
|
65
|
-
|
|
65
|
+
// indicate number of removed elements
|
|
66
|
+
return -els.length
|
|
66
67
|
}
|
|
67
68
|
|
|
68
69
|
directives[':each'] = (tpl, expr, state) => {
|
|
@@ -124,7 +125,7 @@ directives[':each'] = (tpl, expr, state) => {
|
|
|
124
125
|
}
|
|
125
126
|
})
|
|
126
127
|
|
|
127
|
-
return
|
|
128
|
+
return -1 // count back for 1
|
|
128
129
|
}
|
|
129
130
|
|
|
130
131
|
// This was taken AlpineJS, former VueJS 2.* core. Thanks Alpine & Vue!
|
package/test/test.js
CHANGED
|
@@ -170,6 +170,11 @@ test('conditions: reactive values', async () => {
|
|
|
170
170
|
is(el.innerHTML, '<span>4</span>')
|
|
171
171
|
})
|
|
172
172
|
|
|
173
|
+
test('conditions (#3): subsequent content is not abandoned', async () => {
|
|
174
|
+
let x = h`<x><y :if="!!y"></y><z :text="123"></z></x>`
|
|
175
|
+
sprae(x, {y: false})
|
|
176
|
+
is(x.outerHTML, `<x><z>123</z></x>`)
|
|
177
|
+
})
|
|
173
178
|
|
|
174
179
|
test('each: array', async () => {
|
|
175
180
|
// FIXME: in some conspicuous reason jsdom fails to update text nodes somehow
|
|
@@ -419,4 +424,18 @@ test('scope directives must come first', async () => {
|
|
|
419
424
|
let a = h`<x :text="y" :with="{y:1}" :ref="x"></x>`
|
|
420
425
|
sprae(a, {})
|
|
421
426
|
is(a.outerHTML, `<x>1</x>`)
|
|
427
|
+
})
|
|
428
|
+
|
|
429
|
+
test.todo('getters', async () => {
|
|
430
|
+
// let x = h`<x>
|
|
431
|
+
// <h2 :if="doubledCount > 10">YAY!</h2>
|
|
432
|
+
// <button :text="count" :on="{click:increment}"/>
|
|
433
|
+
// <button :text="doubledCount" :on="{click:increment}"/>
|
|
434
|
+
// </x>`
|
|
435
|
+
// document.body.appendChild(x)
|
|
436
|
+
// sprae(x, {
|
|
437
|
+
// count:0,
|
|
438
|
+
// get doubledCount(){return this.count * 2},
|
|
439
|
+
// increment(){ this.count++ }
|
|
440
|
+
// })
|
|
422
441
|
})
|