sprae 5.0.3 → 5.1.0
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 +1 -1
- package/readme.md +2 -2
- package/sprae.auto.js +9 -10
- package/sprae.auto.min.js +1 -1
- package/sprae.js +9 -10
- package/sprae.min.js +1 -1
- package/src/directives.js +3 -3
- package/src/state.js +4 -8
- package/test/dom.js +23 -2
- package/test/index.html +3 -2
- package/todo.md +1 -1
package/package.json
CHANGED
package/readme.md
CHANGED
|
@@ -249,8 +249,8 @@ Expressions are sandboxed, ie. have no access to global or window (since sprae c
|
|
|
249
249
|
<!-- window is undefined -->
|
|
250
250
|
```
|
|
251
251
|
|
|
252
|
-
Default sandbox provides: _Array_, _Object_, _Number_, _String_, _Boolean_, _Date_,
|
|
253
|
-
Sandbox can be extended as `Object.assign(sprae.globals, { BigInt
|
|
252
|
+
Default sandbox provides: _window_, _document_, _console_, _history_, _location_, _Array_, _Object_, _Number_, _String_, _Boolean_, _Date_, _Set_, _Map_.<br/>
|
|
253
|
+
Sandbox can be extended as `Object.assign(sprae.globals, { BigInt })`.
|
|
254
254
|
|
|
255
255
|
## Examples
|
|
256
256
|
|
package/sprae.auto.js
CHANGED
|
@@ -46,7 +46,11 @@
|
|
|
46
46
|
String,
|
|
47
47
|
Boolean,
|
|
48
48
|
Date,
|
|
49
|
-
console
|
|
49
|
+
console,
|
|
50
|
+
window,
|
|
51
|
+
document,
|
|
52
|
+
history,
|
|
53
|
+
location
|
|
50
54
|
};
|
|
51
55
|
var handler = {
|
|
52
56
|
has() {
|
|
@@ -57,9 +61,7 @@
|
|
|
57
61
|
return target[prop];
|
|
58
62
|
if (!(prop in target))
|
|
59
63
|
return target[_parent]?.[prop];
|
|
60
|
-
if (Array.isArray(target) && prop in Array.prototype)
|
|
61
|
-
return target[prop];
|
|
62
|
-
if (prop in Object.prototype)
|
|
64
|
+
if (prop in Object.prototype || Array.isArray(target) && prop in Array.prototype && prop !== "length")
|
|
63
65
|
return target[prop];
|
|
64
66
|
let value = target[prop];
|
|
65
67
|
if (currentFx) {
|
|
@@ -82,10 +84,7 @@
|
|
|
82
84
|
set(target, prop, value) {
|
|
83
85
|
if (!(prop in target) && (target[_parent] && prop in target[_parent]))
|
|
84
86
|
return target[_parent][prop] = value;
|
|
85
|
-
if (Array.isArray(target) && prop
|
|
86
|
-
return target[prop] = value;
|
|
87
|
-
const prev = target[prop];
|
|
88
|
-
if (Object.is(prev, value))
|
|
87
|
+
if (!Array.isArray(target) && Object.is(target[prop], value))
|
|
89
88
|
return true;
|
|
90
89
|
target[prop] = value;
|
|
91
90
|
let propFxs = targetFxs.get(target)?.[prop];
|
|
@@ -308,11 +307,11 @@
|
|
|
308
307
|
};
|
|
309
308
|
secondary["class"] = (el, expr) => {
|
|
310
309
|
let evaluate = parseExpr(el, expr, ":class");
|
|
311
|
-
let initClassName = el.
|
|
310
|
+
let initClassName = el.getAttribute("class");
|
|
312
311
|
return (state2) => {
|
|
313
312
|
let v = evaluate(state2);
|
|
314
313
|
let className = typeof v === "string" ? v : (Array.isArray(v) ? v : Object.entries(v).map(([k, v2]) => v2 ? k : "")).filter(Boolean).join(" ");
|
|
315
|
-
el.
|
|
314
|
+
el.setAttribute("class", [initClassName, className].filter(Boolean).join(" "));
|
|
316
315
|
};
|
|
317
316
|
};
|
|
318
317
|
secondary["style"] = (el, expr) => {
|
package/sprae.auto.min.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
(()=>{var e,t,r=Promise.prototype.then.bind(Promise.resolve()),n=new WeakMap,l=class extends Map{#e=new FinalizationRegistry((e=>super.delete(e)));get size(){return[...this].length}constructor(e=[]){super();for(const[t,r]of e)this.set(t,r)}get(e){return super.get(e)?.deref()}set(e,t){let r=super.get(e);return r&&this.#e.unregister(r),r=(e=>n.get(e)||(e=>{const t=new WeakRef(e);return n.set(e,t),t})(e))(t),this.#e.register(t,e,r),super.set(e,r)}},s=new Set,i=new WeakMap,o=new WeakMap,a=new WeakMap,u=Symbol("parent"),c={Array:Array,Object:Object,Number:Number,String:String,Boolean:Boolean,Date:Date,console:console},f={has:()=>!0,get(t,r){if("symbol"==typeof r)return t[r];if(!(r in t))return t[u]?.[r];if(Array.isArray(t)&&r in Array.prototype
|
|
1
|
+
(()=>{var e,t,r=Promise.prototype.then.bind(Promise.resolve()),n=new WeakMap,l=class extends Map{#e=new FinalizationRegistry((e=>super.delete(e)));get size(){return[...this].length}constructor(e=[]){super();for(const[t,r]of e)this.set(t,r)}get(e){return super.get(e)?.deref()}set(e,t){let r=super.get(e);return r&&this.#e.unregister(r),r=(e=>n.get(e)||(e=>{const t=new WeakRef(e);return n.set(e,t),t})(e))(t),this.#e.register(t,e,r),super.set(e,r)}},s=new Set,i=new WeakMap,o=new WeakMap,a=new WeakMap,u=Symbol("parent"),c={Array:Array,Object:Object,Number:Number,String:String,Boolean:Boolean,Date:Date,console:console,window:window,document:document,history:history,location:location},f={has:()=>!0,get(t,r){if("symbol"==typeof r)return t[r];if(!(r in t))return t[u]?.[r];if(r in Object.prototype||Array.isArray(t)&&r in Array.prototype&&"length"!==r)return t[r];let n=t[r];if(e){let n=i.get(t);n||i.set(t,n={}),n[r]?n[r].includes(e)||n[r].push(e):n[r]=[e]}if(n&&n.constructor===Object||Array.isArray(n)){let e=o.get(n);return e||o.set(n,e=new Proxy(n,f)),e}return n},set(e,t,r){if(!(t in e)&&e[u]&&t in e[u])return e[u][t]=r;if(!Array.isArray(e)&&Object.is(e[t],r))return!0;e[t]=r;let n=i.get(e)?.[t];if(n)for(let e of n)s.add(e);return h(),!0},deleteProperty:(e,t)=>(e[t]=void 0,delete e[t],!0)},p=(e,t)=>{if(o.has(e))return o.get(e);if(a.has(e))return e;let r=new Proxy(e,f);return o.set(e,r),a.set(r,e),e[u]=t?p(t):c,r},y=t=>{const r=()=>{let n=e;e=r,t(),e=n};return r(),r},h=()=>{t||(t=!0,r((()=>{for(let e of s)e.call();s.clear(),t=!1})))},d={},g={};d.if=(e,t)=>{let r=document.createTextNode(""),n=[E(e,t,":if")],l=[e],s=e;for(;(s=e.nextElementSibling)&&s.hasAttribute(":else");)s.removeAttribute(":else"),(t=s.getAttribute(":if"))?(s.removeAttribute(":if"),s.remove(),l.push(s),n.push(E(e,t,":else :if"))):(s.remove(),l.push(s),n.push((()=>1)));return e.replaceWith(s=r),e=>{let t=n.findIndex((t=>t(e)));l[t]!=s&&((s[m]||s).replaceWith(s=l[t]||r),$(s,e))}},d.with=(e,t,r)=>{const n=E(e,t,":with")(r);$(e,p(n,r))};var m=Symbol(":each");d.each=(e,t)=>{let r=function(e){let t=/,([^,\}\]]*)(?:,([^,\}\]]*))?$/,r=e.match(/([\s\S]*?)\s+(?:in|of)\s+([\s\S]*)/);if(!r)return;let n=r[2].trim(),l=r[1].replace(/^\s*\(|\)\s*$/g,"").trim(),s=l.match(t);return s?[l.replace(t,"").trim(),s[1].trim(),n]:[l,"",n]}(t);if(!r)return N(new Error,e,t,":each");const n=e[m]=document.createTextNode("");e.replaceWith(n);const s=E(e,r[2],":each"),i=e.getAttribute(":key"),o=i?E(null,i,":each"):null;e.removeAttribute(":key");const a=e.getAttribute(":ref"),u=new l,c=new l;let f=[];return l=>{let i=s(l);i?"number"==typeof i?i=Array.from({length:i},((e,t)=>[t,t+1])):Array.isArray(i)?i=i.map(((e,t)=>[t+1,e])):"object"==typeof i?i=Object.entries(i):N(Error("Bad list value"),e,t,":each"):i=[];let y=[],h=[];for(let[t,n]of i){let s,i,f=o?.({[r[0]]:n,[r[1]]:t});null==f?s=e.cloneNode(!0):(s=c.get(f))||c.set(f,s=e.cloneNode(!0)),y.push(s),null!=f&&(i=u.get(f))?i[r[0]]=n:(i=p({[r[0]]:n,[a||""]:null,[r[1]]:t},l),null!=f&&u.set(f,i)),h.push(i)}!function(e,t,r,n){const l=new Map,s=new Map;let i,o;for(i=0;i<t.length;i++)l.set(t[i],i);for(i=0;i<r.length;i++)s.set(r[i],i);for(i=o=0;i!==t.length||o!==r.length;){var a=t[i],u=r[o];if(null===a)i++;else if(r.length<=o)e.removeChild(t[i]),i++;else if(t.length<=i)e.insertBefore(u,t[i]||n),o++;else if(a===u)i++,o++;else{var c=s.get(a),f=l.get(u);void 0===c?(e.removeChild(t[i]),i++):void 0===f?(e.insertBefore(u,t[i]||n),o++):(e.insertBefore(t[f],t[i]||n),t[f]=null,f>i+1&&i++,o++)}}}(n.parentNode,f,y,n),f=y;for(let e=0;e<y.length;e++)$(y[e],h[e])}},d.ref=(e,t,r)=>{r[t]=e},g.render=(e,t,r)=>{let n=E(e,t,":render")(r);n||N(new Error("Template not found"),e,t,":render");let l=n.content.cloneNode(!0);e.replaceChildren(l),$(e,r)},g.id=(e,t)=>{let r=E(e,t,":id");return t=>{return n=r(t),e.id=n||0===n?n:"";var n}},g.class=(e,t)=>{let r=E(e,t,":class"),n=e.getAttribute("class");return t=>{let l=r(t),s="string"==typeof l?l:(Array.isArray(l)?l:Object.entries(l).map((([e,t])=>t?e:""))).filter(Boolean).join(" ");e.setAttribute("class",[n,s].filter(Boolean).join(" "))}},g.style=(e,t)=>{let r=E(e,t,":style"),n=e.getAttribute("style")||"";return n.endsWith(";")||(n+="; "),t=>{let l=r(t);if("string"==typeof l)e.setAttribute("style",n+l);else{e.setAttribute("style",n);for(let t in l)e.style.setProperty(t,l[t])}}},g.text=(e,t)=>{let r=E(e,t,":text");return t=>{let n=r(t);e.textContent=null==n?"":n}},g[""]=(e,t)=>{let r=E(e,t,":");if(r)return t=>{let n=r(t);for(let t in n)x(e,t.replace(/[A-Z\u00C0-\u00D6\u00D8-\u00DE]/g,(e=>"-"+e.toLowerCase())),n[t])}},g.value=(e,t)=>{let r,n,l=E(e,t,":value"),s="text"===e.type||""===e.type?t=>e.setAttribute("value",e.value=null==t?"":t):"TEXTAREA"===e.tagName||"text"===e.type||""===e.type?t=>(r=e.selectionStart,n=e.selectionEnd,e.setAttribute("value",e.value=null==t?"":t),r&&e.setSelectionRange(r,n)):"checkbox"===e.type?t=>(e.value=t?"on":"",x(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 e=>s(l(e))},g.on=(e,t)=>{let r=E(e,t,":on");return t=>{let n=r(t),l=[];for(let t in n)l.push(v(e,t,n[t]));return()=>{for(let e of l)e()}}};var b=(e,t,r,n)=>{let l=n.startsWith("on")&&n.slice(2),s=E(e,t,":"+n);if(s)return l?t=>{let r=s(t)||(()=>{});return v(e,l,r)}:t=>x(e,n,s(t))},v=(e,t,r)=>{if(!r)return;let n=t.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,n="")=>(r.test=A[t]?.(r,...n.split("-"))||r.test,""))),r}));if(1==n.length)return i(r,n[0]);const l=(t,r=0)=>{let s;return s=i((i=>{r&&s();let o=t.call(e,i);"function"!=typeof o&&(o=()=>{}),r+1<n.length&&l(o,r?r+1:1)}),n[r])};let s=l(r);return()=>s();function i(e,{evt:t,target:r,test:n,defer:l,stop:s,prevent:i,...o}){l&&(e=l(e));let a=t=>n(t)&&(s&&t.stopPropagation(),i&&t.preventDefault(),e.call(r,t));return r.addEventListener(t,a,o),()=>r.removeEventListener(t,a,o)}},A={prevent(e){e.prevent=!0},stop(e){e.stop=!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},toggle(e){e.defer=(t,r)=>n=>r?(r.call?.(e.target,n),r=null):r=t()},throttle(e,t){e.defer=e=>k(e,t?Number(t)||0:108)},debounce(e,t){e.defer=e=>W(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=>w.ctrl(e)&&t.every((t=>w[t]?w[t](e):e.key===t)),shift:(e,...t)=>e=>w.shift(e)&&t.every((t=>w[t]?w[t](e):e.key===t)),alt:(e,...t)=>e=>w.alt(e)&&t.every((t=>w[t]?w[t](e):e.key===t)),meta:(e,...t)=>e=>w.meta(e)&&t.every((t=>w[t]?w[t](e):e.key===t)),arrow:e=>w.arrow,enter:e=>w.enter,escape:e=>w.escape,tab:e=>w.tab,space:e=>w.space,backspace:e=>w.backspace,delete:e=>w.delete,digit:e=>w.digit,letter:e=>w.letter,character:e=>w.character},w={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,escape:e=>e.key.startsWith("Esc"),tab:e=>"Tab"===e.key,space:e=>" "===e.key||"Space"===e.key||" "===e.key,backspace:e=>"Backspace"===e.key,delete:e=>"Delete"===e.key,digit:e=>/^\d$/.test(e.key),letter:e=>/^[a-zA-Z]$/.test(e.key),character:e=>/^\S$/.test(e.key)},k=(e,t)=>{let r,n,l=s=>{r=!0,setTimeout((()=>{if(r=!1,n)return n=!1,l(s),e(s)}),t)};return t=>r?n=!0:(l(t),e(t))},W=(e,t)=>{let r;return n=>{clearTimeout(r),r=setTimeout((()=>{r=null,e(n)}),t)}},x=(e,t,r)=>{null==r||!1===r?e.removeAttribute(t):e.setAttribute(t,!0===r?"":"number"==typeof r||"string"==typeof r?r:"")},S={};function E(e,t,r){let n=S[t];if(!n){let l=/^[\n\s]*if.*\(.*\)/.test(t)||/\b(let|const)\s/.test(t)&&!r.startsWith(":on")?`(() => {${t}})()`:t;try{n=S[t]=new Function("__scope",`with (__scope) { return ${l.trim()} };`)}catch(n){return N(n,e,t,r)}}return l=>{let s;try{s=n.call(e,l)}catch(n){return N(n,e,t,r)}return s}}function N(e,t,n,l){Object.assign(e,{element:t,expression:n}),console.warn(`∴ ${e.message}\n\n${l}=${n?`"${n}"\n\n`:""}`,t),r((()=>{throw e}),0)}$.globals=c;var j=new WeakMap;function $(e,t){if(!e.children)return;if(j.has(e))return Object.assign(j.get(e),t);const r=p(t||{}),n=[],l=(e,t=e.parentNode)=>{for(let l in d){let s=":"+l;if(e.hasAttribute?.(s)){let i=e.getAttribute(s);if(e.removeAttribute(s),n.push(d[l](e,i,r,l)),j.has(e))return;if(e.parentNode!==t)return!1}}if(e.attributes)for(let t=0;t<e.attributes.length;){let l=e.attributes[t];if(":"!==l.name[0]){t++;continue}e.removeAttribute(l.name);let s=l.value,i=l.name.slice(1).split(":");for(let t of i){let l=g[t]||b;n.push(l(e,s,r,t))}}for(let t,r=0;t=e.children[r];r++)!1===l(t,e)&&r--};l(e);for(let e of n)if(e){let t;y((()=>{"function"==typeof t&&t(),t=e(r)}))}return j.set(e,r),r}document.currentScript&&$(document.documentElement)})();
|
package/sprae.js
CHANGED
|
@@ -45,7 +45,11 @@ var sandbox = {
|
|
|
45
45
|
String,
|
|
46
46
|
Boolean,
|
|
47
47
|
Date,
|
|
48
|
-
console
|
|
48
|
+
console,
|
|
49
|
+
window,
|
|
50
|
+
document,
|
|
51
|
+
history,
|
|
52
|
+
location
|
|
49
53
|
};
|
|
50
54
|
var handler = {
|
|
51
55
|
has() {
|
|
@@ -56,9 +60,7 @@ var handler = {
|
|
|
56
60
|
return target[prop];
|
|
57
61
|
if (!(prop in target))
|
|
58
62
|
return target[_parent]?.[prop];
|
|
59
|
-
if (Array.isArray(target) && prop in Array.prototype)
|
|
60
|
-
return target[prop];
|
|
61
|
-
if (prop in Object.prototype)
|
|
63
|
+
if (prop in Object.prototype || Array.isArray(target) && prop in Array.prototype && prop !== "length")
|
|
62
64
|
return target[prop];
|
|
63
65
|
let value = target[prop];
|
|
64
66
|
if (currentFx) {
|
|
@@ -81,10 +83,7 @@ var handler = {
|
|
|
81
83
|
set(target, prop, value) {
|
|
82
84
|
if (!(prop in target) && (target[_parent] && prop in target[_parent]))
|
|
83
85
|
return target[_parent][prop] = value;
|
|
84
|
-
if (Array.isArray(target) && prop
|
|
85
|
-
return target[prop] = value;
|
|
86
|
-
const prev = target[prop];
|
|
87
|
-
if (Object.is(prev, value))
|
|
86
|
+
if (!Array.isArray(target) && Object.is(target[prop], value))
|
|
88
87
|
return true;
|
|
89
88
|
target[prop] = value;
|
|
90
89
|
let propFxs = targetFxs.get(target)?.[prop];
|
|
@@ -307,11 +306,11 @@ secondary["id"] = (el, expr) => {
|
|
|
307
306
|
};
|
|
308
307
|
secondary["class"] = (el, expr) => {
|
|
309
308
|
let evaluate = parseExpr(el, expr, ":class");
|
|
310
|
-
let initClassName = el.
|
|
309
|
+
let initClassName = el.getAttribute("class");
|
|
311
310
|
return (state2) => {
|
|
312
311
|
let v = evaluate(state2);
|
|
313
312
|
let className = typeof v === "string" ? v : (Array.isArray(v) ? v : Object.entries(v).map(([k, v2]) => v2 ? k : "")).filter(Boolean).join(" ");
|
|
314
|
-
el.
|
|
313
|
+
el.setAttribute("class", [initClassName, className].filter(Boolean).join(" "));
|
|
315
314
|
};
|
|
316
315
|
};
|
|
317
316
|
secondary["style"] = (el, expr) => {
|
package/sprae.min.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
var e,t,r=Promise.prototype.then.bind(Promise.resolve()),n=new WeakMap,l=class extends Map{#e=new FinalizationRegistry((e=>super.delete(e)));get size(){return[...this].length}constructor(e=[]){super();for(const[t,r]of e)this.set(t,r)}get(e){return super.get(e)?.deref()}set(e,t){let r=super.get(e);return r&&this.#e.unregister(r),r=(e=>n.get(e)||(e=>{const t=new WeakRef(e);return n.set(e,t),t})(e))(t),this.#e.register(t,e,r),super.set(e,r)}},s=new Set,i=new WeakMap,o=new WeakMap,a=new WeakMap,u=Symbol("parent"),c={Array:Array,Object:Object,Number:Number,String:String,Boolean:Boolean,Date:Date,console:console},f={has:()=>!0,get(t,r){if("symbol"==typeof r)return t[r];if(!(r in t))return t[u]?.[r];if(Array.isArray(t)&&r in Array.prototype
|
|
1
|
+
var e,t,r=Promise.prototype.then.bind(Promise.resolve()),n=new WeakMap,l=class extends Map{#e=new FinalizationRegistry((e=>super.delete(e)));get size(){return[...this].length}constructor(e=[]){super();for(const[t,r]of e)this.set(t,r)}get(e){return super.get(e)?.deref()}set(e,t){let r=super.get(e);return r&&this.#e.unregister(r),r=(e=>n.get(e)||(e=>{const t=new WeakRef(e);return n.set(e,t),t})(e))(t),this.#e.register(t,e,r),super.set(e,r)}},s=new Set,i=new WeakMap,o=new WeakMap,a=new WeakMap,u=Symbol("parent"),c={Array:Array,Object:Object,Number:Number,String:String,Boolean:Boolean,Date:Date,console:console,window:window,document:document,history:history,location:location},f={has:()=>!0,get(t,r){if("symbol"==typeof r)return t[r];if(!(r in t))return t[u]?.[r];if(r in Object.prototype||Array.isArray(t)&&r in Array.prototype&&"length"!==r)return t[r];let n=t[r];if(e){let n=i.get(t);n||i.set(t,n={}),n[r]?n[r].includes(e)||n[r].push(e):n[r]=[e]}if(n&&n.constructor===Object||Array.isArray(n)){let e=o.get(n);return e||o.set(n,e=new Proxy(n,f)),e}return n},set(e,t,r){if(!(t in e)&&e[u]&&t in e[u])return e[u][t]=r;if(!Array.isArray(e)&&Object.is(e[t],r))return!0;e[t]=r;let n=i.get(e)?.[t];if(n)for(let e of n)s.add(e);return h(),!0},deleteProperty:(e,t)=>(e[t]=void 0,delete e[t],!0)},p=(e,t)=>{if(o.has(e))return o.get(e);if(a.has(e))return e;let r=new Proxy(e,f);return o.set(e,r),a.set(r,e),e[u]=t?p(t):c,r},y=t=>{const r=()=>{let n=e;e=r,t(),e=n};return r(),r},h=()=>{t||(t=!0,r((()=>{for(let e of s)e.call();s.clear(),t=!1})))},d={},g={};d.if=(e,t)=>{let r=document.createTextNode(""),n=[E(e,t,":if")],l=[e],s=e;for(;(s=e.nextElementSibling)&&s.hasAttribute(":else");)s.removeAttribute(":else"),(t=s.getAttribute(":if"))?(s.removeAttribute(":if"),s.remove(),l.push(s),n.push(E(e,t,":else :if"))):(s.remove(),l.push(s),n.push((()=>1)));return e.replaceWith(s=r),e=>{let t=n.findIndex((t=>t(e)));l[t]!=s&&((s[m]||s).replaceWith(s=l[t]||r),$(s,e))}},d.with=(e,t,r)=>{const n=E(e,t,":with")(r);$(e,p(n,r))};var m=Symbol(":each");d.each=(e,t)=>{let r=function(e){let t=/,([^,\}\]]*)(?:,([^,\}\]]*))?$/,r=e.match(/([\s\S]*?)\s+(?:in|of)\s+([\s\S]*)/);if(!r)return;let n=r[2].trim(),l=r[1].replace(/^\s*\(|\)\s*$/g,"").trim(),s=l.match(t);return s?[l.replace(t,"").trim(),s[1].trim(),n]:[l,"",n]}(t);if(!r)return N(new Error,e,t,":each");const n=e[m]=document.createTextNode("");e.replaceWith(n);const s=E(e,r[2],":each"),i=e.getAttribute(":key"),o=i?E(null,i,":each"):null;e.removeAttribute(":key");const a=e.getAttribute(":ref"),u=new l,c=new l;let f=[];return l=>{let i=s(l);i?"number"==typeof i?i=Array.from({length:i},((e,t)=>[t,t+1])):Array.isArray(i)?i=i.map(((e,t)=>[t+1,e])):"object"==typeof i?i=Object.entries(i):N(Error("Bad list value"),e,t,":each"):i=[];let y=[],h=[];for(let[t,n]of i){let s,i,f=o?.({[r[0]]:n,[r[1]]:t});null==f?s=e.cloneNode(!0):(s=c.get(f))||c.set(f,s=e.cloneNode(!0)),y.push(s),null!=f&&(i=u.get(f))?i[r[0]]=n:(i=p({[r[0]]:n,[a||""]:null,[r[1]]:t},l),null!=f&&u.set(f,i)),h.push(i)}!function(e,t,r,n){const l=new Map,s=new Map;let i,o;for(i=0;i<t.length;i++)l.set(t[i],i);for(i=0;i<r.length;i++)s.set(r[i],i);for(i=o=0;i!==t.length||o!==r.length;){var a=t[i],u=r[o];if(null===a)i++;else if(r.length<=o)e.removeChild(t[i]),i++;else if(t.length<=i)e.insertBefore(u,t[i]||n),o++;else if(a===u)i++,o++;else{var c=s.get(a),f=l.get(u);void 0===c?(e.removeChild(t[i]),i++):void 0===f?(e.insertBefore(u,t[i]||n),o++):(e.insertBefore(t[f],t[i]||n),t[f]=null,f>i+1&&i++,o++)}}}(n.parentNode,f,y,n),f=y;for(let e=0;e<y.length;e++)$(y[e],h[e])}},d.ref=(e,t,r)=>{r[t]=e},g.render=(e,t,r)=>{let n=E(e,t,":render")(r);n||N(new Error("Template not found"),e,t,":render");let l=n.content.cloneNode(!0);e.replaceChildren(l),$(e,r)},g.id=(e,t)=>{let r=E(e,t,":id");return t=>{return n=r(t),e.id=n||0===n?n:"";var n}},g.class=(e,t)=>{let r=E(e,t,":class"),n=e.getAttribute("class");return t=>{let l=r(t),s="string"==typeof l?l:(Array.isArray(l)?l:Object.entries(l).map((([e,t])=>t?e:""))).filter(Boolean).join(" ");e.setAttribute("class",[n,s].filter(Boolean).join(" "))}},g.style=(e,t)=>{let r=E(e,t,":style"),n=e.getAttribute("style")||"";return n.endsWith(";")||(n+="; "),t=>{let l=r(t);if("string"==typeof l)e.setAttribute("style",n+l);else{e.setAttribute("style",n);for(let t in l)e.style.setProperty(t,l[t])}}},g.text=(e,t)=>{let r=E(e,t,":text");return t=>{let n=r(t);e.textContent=null==n?"":n}},g[""]=(e,t)=>{let r=E(e,t,":");if(r)return t=>{let n=r(t);for(let t in n)x(e,t.replace(/[A-Z\u00C0-\u00D6\u00D8-\u00DE]/g,(e=>"-"+e.toLowerCase())),n[t])}},g.value=(e,t)=>{let r,n,l=E(e,t,":value"),s="text"===e.type||""===e.type?t=>e.setAttribute("value",e.value=null==t?"":t):"TEXTAREA"===e.tagName||"text"===e.type||""===e.type?t=>(r=e.selectionStart,n=e.selectionEnd,e.setAttribute("value",e.value=null==t?"":t),r&&e.setSelectionRange(r,n)):"checkbox"===e.type?t=>(e.value=t?"on":"",x(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 e=>s(l(e))},g.on=(e,t)=>{let r=E(e,t,":on");return t=>{let n=r(t),l=[];for(let t in n)l.push(v(e,t,n[t]));return()=>{for(let e of l)e()}}};var b=(e,t,r,n)=>{let l=n.startsWith("on")&&n.slice(2),s=E(e,t,":"+n);if(s)return l?t=>{let r=s(t)||(()=>{});return v(e,l,r)}:t=>x(e,n,s(t))},v=(e,t,r)=>{if(!r)return;let n=t.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,n="")=>(r.test=A[t]?.(r,...n.split("-"))||r.test,""))),r}));if(1==n.length)return i(r,n[0]);const l=(t,r=0)=>{let s;return s=i((i=>{r&&s();let o=t.call(e,i);"function"!=typeof o&&(o=()=>{}),r+1<n.length&&l(o,r?r+1:1)}),n[r])};let s=l(r);return()=>s();function i(e,{evt:t,target:r,test:n,defer:l,stop:s,prevent:i,...o}){l&&(e=l(e));let a=t=>n(t)&&(s&&t.stopPropagation(),i&&t.preventDefault(),e.call(r,t));return r.addEventListener(t,a,o),()=>r.removeEventListener(t,a,o)}},A={prevent(e){e.prevent=!0},stop(e){e.stop=!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},toggle(e){e.defer=(t,r)=>n=>r?(r.call?.(e.target,n),r=null):r=t()},throttle(e,t){e.defer=e=>k(e,t?Number(t)||0:108)},debounce(e,t){e.defer=e=>W(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=>w.ctrl(e)&&t.every((t=>w[t]?w[t](e):e.key===t)),shift:(e,...t)=>e=>w.shift(e)&&t.every((t=>w[t]?w[t](e):e.key===t)),alt:(e,...t)=>e=>w.alt(e)&&t.every((t=>w[t]?w[t](e):e.key===t)),meta:(e,...t)=>e=>w.meta(e)&&t.every((t=>w[t]?w[t](e):e.key===t)),arrow:e=>w.arrow,enter:e=>w.enter,escape:e=>w.escape,tab:e=>w.tab,space:e=>w.space,backspace:e=>w.backspace,delete:e=>w.delete,digit:e=>w.digit,letter:e=>w.letter,character:e=>w.character},w={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,escape:e=>e.key.startsWith("Esc"),tab:e=>"Tab"===e.key,space:e=>" "===e.key||"Space"===e.key||" "===e.key,backspace:e=>"Backspace"===e.key,delete:e=>"Delete"===e.key,digit:e=>/^\d$/.test(e.key),letter:e=>/^[a-zA-Z]$/.test(e.key),character:e=>/^\S$/.test(e.key)},k=(e,t)=>{let r,n,l=s=>{r=!0,setTimeout((()=>{if(r=!1,n)return n=!1,l(s),e(s)}),t)};return t=>r?n=!0:(l(t),e(t))},W=(e,t)=>{let r;return n=>{clearTimeout(r),r=setTimeout((()=>{r=null,e(n)}),t)}},x=(e,t,r)=>{null==r||!1===r?e.removeAttribute(t):e.setAttribute(t,!0===r?"":"number"==typeof r||"string"==typeof r?r:"")},S={};function E(e,t,r){let n=S[t];if(!n){let l=/^[\n\s]*if.*\(.*\)/.test(t)||/\b(let|const)\s/.test(t)&&!r.startsWith(":on")?`(() => {${t}})()`:t;try{n=S[t]=new Function("__scope",`with (__scope) { return ${l.trim()} };`)}catch(n){return N(n,e,t,r)}}return l=>{let s;try{s=n.call(e,l)}catch(n){return N(n,e,t,r)}return s}}function N(e,t,n,l){Object.assign(e,{element:t,expression:n}),console.warn(`∴ ${e.message}\n\n${l}=${n?`"${n}"\n\n`:""}`,t),r((()=>{throw e}),0)}$.globals=c;var j=new WeakMap;function $(e,t){if(!e.children)return;if(j.has(e))return Object.assign(j.get(e),t);const r=p(t||{}),n=[],l=(e,t=e.parentNode)=>{for(let l in d){let s=":"+l;if(e.hasAttribute?.(s)){let i=e.getAttribute(s);if(e.removeAttribute(s),n.push(d[l](e,i,r,l)),j.has(e))return;if(e.parentNode!==t)return!1}}if(e.attributes)for(let t=0;t<e.attributes.length;){let l=e.attributes[t];if(":"!==l.name[0]){t++;continue}e.removeAttribute(l.name);let s=l.value,i=l.name.slice(1).split(":");for(let t of i){let l=g[t]||b;n.push(l(e,s,r,t))}}for(let t,r=0;t=e.children[r];r++)!1===l(t,e)&&r--};l(e);for(let e of n)if(e){let t;y((()=>{"function"==typeof t&&t(),t=e(r)}))}return j.set(e,r),r}var C=$;document.currentScript&&$(document.documentElement);export{C as default};
|
package/src/directives.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
// directives & parsing
|
|
2
2
|
import sprae from './core.js'
|
|
3
3
|
import swap from './domdiff.js'
|
|
4
|
+
// import swap from 'swapdom'
|
|
4
5
|
import { state as createState} from './state.js'
|
|
5
6
|
import { queueMicrotask, WeakishMap } from './util.js'
|
|
6
7
|
|
|
@@ -49,7 +50,6 @@ primary['with'] = (el, expr, rootState) => {
|
|
|
49
50
|
let evaluate = parseExpr(el, expr, ':with')
|
|
50
51
|
const localState = evaluate(rootState)
|
|
51
52
|
let state = createState(localState, rootState)
|
|
52
|
-
// console.log(123, state.foo, state.bar)
|
|
53
53
|
sprae(el, state);
|
|
54
54
|
}
|
|
55
55
|
|
|
@@ -169,11 +169,11 @@ secondary['id'] = (el, expr) => {
|
|
|
169
169
|
|
|
170
170
|
secondary['class'] = (el, expr) => {
|
|
171
171
|
let evaluate = parseExpr(el, expr, ':class')
|
|
172
|
-
let initClassName = el.
|
|
172
|
+
let initClassName = el.getAttribute('class')
|
|
173
173
|
return (state) => {
|
|
174
174
|
let v = evaluate(state)
|
|
175
175
|
let className = typeof v === 'string' ? v : (Array.isArray(v) ? v : Object.entries(v).map(([k,v])=>v?k:'')).filter(Boolean).join(' ')
|
|
176
|
-
el.
|
|
176
|
+
el.setAttribute('class',[initClassName, className].filter(Boolean).join(' '));
|
|
177
177
|
}
|
|
178
178
|
}
|
|
179
179
|
|
package/src/state.js
CHANGED
|
@@ -11,7 +11,7 @@ const _parent = Symbol('parent')
|
|
|
11
11
|
// default root sandbox
|
|
12
12
|
export const sandbox = {
|
|
13
13
|
Array, Object, Number, String, Boolean, Date,
|
|
14
|
-
console
|
|
14
|
+
console, window, document, history, location
|
|
15
15
|
}
|
|
16
16
|
|
|
17
17
|
const handler = {
|
|
@@ -23,9 +23,8 @@ const handler = {
|
|
|
23
23
|
get(target, prop) {
|
|
24
24
|
if (typeof prop === 'symbol') return target[prop]
|
|
25
25
|
if (!(prop in target)) return target[_parent]?.[prop]
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
if (prop in Object.prototype) return target[prop];
|
|
26
|
+
// .constructor, .slice etc
|
|
27
|
+
if (prop in Object.prototype || (Array.isArray(target) && prop in Array.prototype && prop !== 'length')) return target[prop];
|
|
29
28
|
|
|
30
29
|
let value = target[prop]
|
|
31
30
|
if (currentFx) {
|
|
@@ -52,12 +51,9 @@ const handler = {
|
|
|
52
51
|
|
|
53
52
|
set(target, prop, value) {
|
|
54
53
|
if (!(prop in target) && (target[_parent] && prop in target[_parent])) return target[_parent][prop] = value
|
|
55
|
-
if (Array.isArray(target) && prop in Array.prototype) return target[prop] = value;
|
|
56
|
-
|
|
57
|
-
const prev = target[prop]
|
|
58
54
|
|
|
59
55
|
// avoid bumping unchanged values
|
|
60
|
-
if (Object.is(
|
|
56
|
+
if (!Array.isArray(target) && Object.is(target[prop], value)) return true
|
|
61
57
|
|
|
62
58
|
target[prop] = value
|
|
63
59
|
|
package/test/dom.js
CHANGED
|
@@ -109,6 +109,18 @@ test('class', async () => {
|
|
|
109
109
|
// is(el.outerHTML, `<x class="base x"></x><y class="y w"></y><z class="b c"></z>`);
|
|
110
110
|
})
|
|
111
111
|
|
|
112
|
+
test('class: old svg fun', async () => {
|
|
113
|
+
// raw html creates svganimatedstring
|
|
114
|
+
let el = document.createElement('div')
|
|
115
|
+
el.innerHTML = `<svg class="foo" :class="a ? 'x' : 'y'"></svg>`
|
|
116
|
+
|
|
117
|
+
let s = sprae(el, {a:true})
|
|
118
|
+
is(el.innerHTML, `<svg class="foo x"></svg>`)
|
|
119
|
+
s.a = false
|
|
120
|
+
await tick()
|
|
121
|
+
is(el.innerHTML, `<svg class="foo y"></svg>`)
|
|
122
|
+
})
|
|
123
|
+
|
|
112
124
|
test('props: base', async () => {
|
|
113
125
|
let el = h`<input :id="0" :="{for:1, title:2, help:3, type:4, placeholder: 5, value: 6, aB: 8}" :value="7"/>`
|
|
114
126
|
let params = sprae(el)
|
|
@@ -1018,13 +1030,22 @@ test.skip('getters', async () => {
|
|
|
1018
1030
|
})
|
|
1019
1031
|
|
|
1020
1032
|
test('sandbox', async () => {
|
|
1021
|
-
let el = h`<x :x="log.push(typeof
|
|
1033
|
+
let el = h`<x :x="log.push(typeof self, typeof console, typeof arguments, typeof __scope)"></x>`
|
|
1022
1034
|
let log = []
|
|
1023
1035
|
sprae(el.cloneNode(), {log})
|
|
1024
1036
|
is(log, ['undefined', 'object', 'undefined', 'undefined'])
|
|
1025
1037
|
|
|
1026
1038
|
log.splice(0)
|
|
1027
|
-
Object.assign(sprae.globals, { window })
|
|
1039
|
+
Object.assign(sprae.globals, { self: window })
|
|
1028
1040
|
sprae(el.cloneNode(), {log})
|
|
1029
1041
|
is(log, ['object', 'object', 'undefined', 'undefined'])
|
|
1042
|
+
})
|
|
1043
|
+
|
|
1044
|
+
test('subscribe to array length', async () => {
|
|
1045
|
+
let el = h`<div :with="{likes:[]}"><x :onx="e=>likes.push(1)"></x><y :text="likes.length"></y></div>`
|
|
1046
|
+
sprae(el)
|
|
1047
|
+
is(el.innerHTML, `<x></x><y>0</y>`)
|
|
1048
|
+
el.firstChild.dispatchEvent(new CustomEvent('x'))
|
|
1049
|
+
await tick()
|
|
1050
|
+
is(el.innerHTML, `<x></x><y>1</y>`)
|
|
1030
1051
|
})
|
package/test/index.html
CHANGED
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
<title>Test</title>
|
|
4
4
|
|
|
5
5
|
<script defer src="../sprae.auto.js"></script>
|
|
6
|
-
<div :with="{data:
|
|
7
|
-
<span :text="data"
|
|
6
|
+
<div :with="{data:'autoinit works'}">
|
|
7
|
+
<span :text="data">autoinit is broken</span>
|
|
8
8
|
</div>
|
|
9
9
|
|
|
10
10
|
<script async src="../node_modules/es-module-shims/dist/es-module-shims.js"></script>
|
|
@@ -33,3 +33,4 @@
|
|
|
33
33
|
</script>
|
|
34
34
|
|
|
35
35
|
<script src="./test.js" type="module"></script>
|
|
36
|
+
|
package/todo.md
CHANGED