sprae 6.1.0 → 6.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/license ADDED
@@ -0,0 +1,7 @@
1
+ Copyright 2022 Dmitry Ivanov
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
4
+
5
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
6
+
7
+ THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
package/package.json CHANGED
@@ -1,10 +1,17 @@
1
1
  {
2
2
  "name": "sprae",
3
3
  "description": "DOM microhydration.",
4
- "version": "6.1.0",
4
+ "version": "6.1.2",
5
5
  "main": "src/index.js",
6
6
  "module": "src/index.js",
7
7
  "type": "module",
8
+ "files": [
9
+ "sprae.auto.js",
10
+ "sprae.auto.min.js",
11
+ "sprae.js",
12
+ "sprae.min.js",
13
+ "src"
14
+ ],
8
15
  "dependencies": {
9
16
  "swapdom": "^1.1.1"
10
17
  },
@@ -47,7 +54,7 @@
47
54
  "templating"
48
55
  ],
49
56
  "author": "Dmitry Ivanov <df.creative@gmail.com>",
50
- "license": "ISC",
57
+ "license": "MIT",
51
58
  "bugs": {
52
59
  "url": "https://github.com/dy/sprae/issues"
53
60
  },
package/readme.md CHANGED
@@ -1,8 +1,8 @@
1
1
  # ∴ spræ [![tests](https://github.com/dy/sprae/actions/workflows/node.js.yml/badge.svg)](https://github.com/dy/sprae/actions/workflows/node.js.yml) [![size](https://img.shields.io/bundlephobia/minzip/sprae?label=size)](https://bundlephobia.com/result?p=sprae) [![npm](https://img.shields.io/npm/v/sprae?color=orange)](https://npmjs.org/sprae)
2
2
 
3
- > DOM microhydration with `:` attributes.
3
+ > DOM tree hydration with reactivity.
4
4
 
5
- _Sprae_ is tiny progressive enhancement framework, a minimal essential alternative to [alpine](https://github.com/alpinejs/alpine)/[lucia](https://github.com/aidenybai/lucia), [petite-vue](https://github.com/vuejs/petite-vue) or [template-parts](https://github.com/github/template-parts) with improved ergonomics[*](#justification--alternatives). It enables simple markup logic without external scripts. Perfect for small websites, prototypes or UI logic.
5
+ _Sprae_ is progressive enhancement framework, a tiny essential alternative to [alpine](https://github.com/alpinejs/alpine), [petite-vue](https://github.com/vuejs/petite-vue) or [template-parts](https://github.com/github/template-parts) with improved ergonomics[*](#justification--alternatives). It enables simple markup logic without external scripts. Perfect for small websites, prototypes or UI logic.
6
6
 
7
7
  ## Use
8
8
 
@@ -14,29 +14,34 @@ To autoinit document, include [`sprae.auto.js`](./sprae.auto.js):
14
14
  <!-- <script src="https://cdn.jsdelivr.net/npm/sprae/sprae.auto.js" defer></script> -->
15
15
  <script src="./path/to/sprae.auto.js" defer></script>
16
16
 
17
- <a :each="id in ['a','b','c']" :href="`#${id}`" :text="id"></a>
17
+ <ul>
18
+ <li :each="item in ['apple', 'bananas', 'citrus']"">
19
+ <a :href="`#${item}`" :text="item" />
20
+ </li>
21
+ </ul>
18
22
  ```
19
23
 
20
24
  ### Manual init
21
25
 
22
- To use as module, import [`sprae.js`](./sprae.js):
26
+ To init manually as module, import [`sprae.js`](./sprae.js):
23
27
 
24
28
  ```html
25
29
  <div id="container" :if="user">
26
- Logged in as <span :text="user.displayName">Guest.</span>
30
+ Logged in as <span :text="user.name">Guest.</span>
27
31
  </div>
28
32
 
29
33
  <script type="module">
30
34
  // import sprae from 'https://cdn.jsdelivr.net/npm/sprae/sprae.js';
31
35
  import sprae from './path/to/sprae.js';
32
36
 
33
- const state = sprae(container, { user: { displayName: 'Dmitry Ivanov' } });
34
- state.user.displayName = 'dy'; // updates DOM
37
+ const state = sprae(container, { user: { name: 'Dmitry Ivanov' } });
38
+ state.user.name = 'dy'; // updates DOM
35
39
  </script>
36
40
  ```
37
41
 
38
- Sprae evaluates `:`-attributes and evaporates them. Reactive `state` reflects current values, can be updated directly.
39
-
42
+ Sprae evaluates `:`-attributes and evaporates them.<br/>
43
+ Reactive `state` reflects current values, can be updated directly.<br/>
44
+ It batches multiple updates internally for efficiency.
40
45
 
41
46
  ## Attributes
42
47
 
@@ -80,14 +85,14 @@ Welcome, <span :text="user.name">Guest</span>.
80
85
 
81
86
  #### `:class="value"`
82
87
 
83
- Set class value from either string, array or object. Extends existing `class` attribute, if any.
88
+ Set class value from either a string, array or object.
84
89
 
85
90
  ```html
91
+ <!-- set from string -->
86
92
  <div :class="`foo ${bar}`"></div>
87
93
 
88
- <!-- extend existing class -->
94
+ <!-- extends existing class as "foo bar" -->
89
95
  <div class="foo" :class="`bar`"></div>
90
- <!-- <div class="foo bar"></div> -->
91
96
 
92
97
  <!-- object with values -->
93
98
  <div :class="{foo:true, bar: false}"></div>
@@ -95,11 +100,16 @@ Set class value from either string, array or object. Extends existing `class` at
95
100
 
96
101
  #### `:style="value"`
97
102
 
98
- Set style value from object or a string. Extends existing `style` attribute, if any.
103
+ Set style value from an object or a string. Extends existing `style` attribute, if any.
99
104
 
100
105
  ```html
101
- <div :style="foo: bar"></div>
106
+ <!-- from string -->
107
+ <div :style="`foo: ${bar}`"></div>
108
+
109
+ <!-- from object -->
102
110
  <div :style="{foo: 'bar'}"></div>
111
+
112
+ <!-- set CSS variable -->
103
113
  <div :style="{'--baz': qux}"></div>
104
114
  ```
105
115
 
@@ -108,9 +118,11 @@ Set style value from object or a string. Extends existing `style` attribute, if
108
118
  Set value of an input, textarea or select. Takes handle of `checked` and `selected` attributes.
109
119
 
110
120
  ```html
111
- <input :value="text" />
112
- <textarea :value="text" />
121
+ <!-- set from value -->
122
+ <input :value="value" />
123
+ <textarea :value="value" />
113
124
 
125
+ <!-- selects right option -->
114
126
  <select :value="selected">
115
127
  <option :each="i in 5" :value="i" :text="i"></option>
116
128
  </select>
@@ -133,15 +145,30 @@ Define or extend data scope for a subtree.
133
145
  </x>
134
146
  ```
135
147
 
136
- #### `:render="ref"`
148
+ #### `:<prop>="value?"`
137
149
 
138
- Include template as element content.
150
+ Set any attribute value or run an effect.
139
151
 
140
152
  ```html
141
- <template :ref="foo"><span :text="foo"></span></template>
153
+ <!-- Single property -->
154
+ <label :for="name" :text="name" />
142
155
 
143
- <div :render="foo" :with="{foo:'bar'}">...inserted here...</div>
144
- <div :render="foo" :with="{foo:'baz'}">...inserted here...</div>
156
+ <!-- Multiple properties -->
157
+ <input :id:name="name" />
158
+
159
+ <!-- Effect - returns undefined, triggers any time bar changes -->
160
+ <div :fx="void bar()" ></div>
161
+
162
+ <!-- Raw event listener (see events) -->
163
+ <div :onclick="e=>e.preventDefault()"></div>
164
+ ```
165
+
166
+ #### `:="props?"`
167
+
168
+ Spread multiple attibures.
169
+
170
+ ```html
171
+ <input :="{ id: name, name, type:'text', value }" />
145
172
  ```
146
173
 
147
174
  #### `:ref="id"`
@@ -161,30 +188,17 @@ Expose element to current data scope with the `id`:
161
188
  </ul>
162
189
  ```
163
190
 
164
- #### `:="props?"`
165
-
166
- Spread multiple attibures.
167
-
168
- ```html
169
- <input :="{ id: name, name, type:'text', value }" />
170
- ```
171
-
172
- #### `:<prop>="value?"`
191
+ #### `:render="ref"`
173
192
 
174
- Set any attribute value or run an effect.
193
+ Include template as element content.
175
194
 
176
195
  ```html
177
- <!-- Single property -->
178
- <label :for="name" :text="name" />
179
-
180
- <!-- Multiple properties -->
181
- <input :id:name="name" />
182
-
183
- <!-- Effect - returns undefined, triggers any time bar changes -->
184
- <div :fx="void bar()" ></div>
196
+ <!-- assign template element to foo variable -->
197
+ <template :ref="foo"><span :text="foo"></span></template>
185
198
 
186
- <!-- Raw event listener (see events) -->
187
- <div :onclick="e=>e.preventDefault()"></div>
199
+ <!-- rended template as content -->
200
+ <div :render="foo" :with="{foo:'bar'}">...inserted here...</div>
201
+ <div :render="foo" :with="{foo:'baz'}">...inserted here...</div>
188
202
  ```
189
203
 
190
204
 
@@ -192,7 +206,7 @@ Set any attribute value or run an effect.
192
206
 
193
207
  #### `@<event>="handle"`, `@<foo>@<bar>.<baz>="handle"`
194
208
 
195
- Attach event(s) listener with possible modifiers. `event` variable holds current event.
209
+ Attach event(s) listener with possible modifiers. `event` variable holds current event. Allows async handlers.
196
210
 
197
211
  ```html
198
212
  <!-- Single event -->
@@ -218,14 +232,15 @@ Attach event(s) listener with possible modifiers. `event` variable holds current
218
232
 
219
233
  ## Sandbox
220
234
 
221
- Expressions are sandboxed, ie. have no access to global or window (since sprae can be run in server environment).
235
+ Expressions are sandboxed, ie. don't access global/window scope by default (since sprae can be run in server environment).
222
236
 
223
237
  ```html
224
- <div :x="global.x"></div>
225
- <!-- global is undefined -->
238
+ <div :x="scrollY"></div>
239
+ <!-- scrollY is undefined -->
226
240
  ```
227
241
 
228
- Default sandbox provides: _window_, _document_, _console_, _history_, _location_, _Array_, _Object_, _Number_, _String_, _Boolean_, _Date_, _Set_, _Map_.<br/>
242
+ Default sandbox provides: _window_, _document_, _console_, _history_, _location_, _Date_, _Set_, _Map_.
243
+
229
244
  Sandbox can be extended as `Object.assign(sprae.globals, { BigInt })`.
230
245
 
231
246
  ## FOUC
@@ -246,7 +261,7 @@ To avoid _flash of unstyled content_, you can hide sprae attribute or add a cust
246
261
  ## Justification & alternatives
247
262
 
248
263
  * [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. Also it's just nice to keep `{{}}` generic, regardless of markup, and attributes as part of markup.
249
- * [Alpine](https://github.com/alpinejs/alpine) / [vue](https://github.com/vuejs/petite-vue) / [lit](https://github.com/lit/lit/tree/main/packages/lit-html) / [lucia](https://github.com/aidenybai/lucia) escape native HTML quirks, but the syntax space (`:attr`, `v-*`,`x-*`, `l-*` `@evt`, `{{}}`) is too broad, as well as functionality. Perfection is when there's nothing to take away, not add (c). Also they tend to [self-encapsulate](https://github.com/alpinejs/alpine/discussions/3223) making interop hard, invent own tooling or complex reactivity.
264
+ * [Alpine](https://github.com/alpinejs/alpine) / [vue](https://github.com/vuejs/petite-vue) / [lit](https://github.com/lit/lit/tree/main/packages/lit-html) escape native HTML quirks, but the syntax space (`:attr`, `v-*`,`x-*`, `l-*` `@evt`, `{{}}`) is too broad, as well as functionality. Perfection is when there's nothing to take away, not add (c). Also they tend to [self-encapsulate](https://github.com/alpinejs/alpine/discussions/3223) making interop hard, invent own tooling or complex reactivity.
250
265
  * React/[preact](https://ghub.io/preact) does the job wiring up JS to HTML, but with an extreme of migrating HTML to JSX and enforcing SPA, which is not organic for HTML. Also it doesn't support reactive fields (needs render call).
251
266
 
252
267
  _Sprae_ takes idea of _templize directives_/_alpine_/_vue_ attrs and builds upon <del>[_@preact/signals_](https://ghub.io/@preact/signals)</del> simple reactive state.
@@ -261,5 +276,10 @@ _Sprae_ takes idea of _templize directives_/_alpine_/_vue_ attrs and builds upon
261
276
 
262
277
  It is reminiscent of [XSLT](https://www.w3schools.com/xml/xsl_intro.asp), considered a [buried treasure](https://github.com/bahrus/be-restated) by web-connoisseurs.
263
278
 
279
+ ## Alternatives
280
+
281
+ * [Alpine](https://github.com/alpinejs/alpine)
282
+ * ~~[Lucia](https://github.com/aidenybai/lucia)~~ deprecated
283
+ * [Petite-vue](https://github.com/vuejs/petite-vue)
264
284
 
265
285
  <p align="center"><a href="https://github.com/krsnzd/license/">🕉</a></p>
package/sprae.auto.js CHANGED
@@ -569,7 +569,7 @@ ${directive}=${expression ? `"${expression}"
569
569
  let attr2 = el.attributes[i], prefix = attr2.name[0];
570
570
  if (prefix === ":" || prefix === "@") {
571
571
  el.removeAttribute(attr2.name);
572
- let expr = prefix === "@" ? `event=>{${attr2.value}}` : attr2.value, names = attr2.name.slice(1).split(prefix);
572
+ let expr = prefix === "@" ? `${attr2.value.includes("await") ? "async" : ""} event=>{${attr2.value}}` : attr2.value, names = attr2.name.slice(1).split(prefix);
573
573
  for (let name of names) {
574
574
  if (prefix === "@")
575
575
  name = `on` + name;
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,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);o.set(e,r),a.set(r,e);let n=Object.getOwnPropertyDescriptors(e);for(let t in n){let l=n[t];l.get&&l.get&&(l.get=l.get.bind(r),Object.defineProperty(e,t,l))}return 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=[j(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(j(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),O(s,e))}};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 E(new Error,e,t,":each");const n=e[m]=document.createTextNode("");e.replaceWith(n);const s=j(e,r[2],":each"),i=e.getAttribute(":key"),o=i?j(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+1,t])):Array.isArray(i)?i=i.map(((e,t)=>[t+1,e])):"object"==typeof i?i=Object.entries(i):E(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++)O(y[e],h[e])}},d.with=(e,t,r)=>{const n=j(e,t,":with")(r);O(e,p(n,r))},d.ref=(e,t,r)=>{r[t]=e},g.render=(e,t,r)=>{let n=j(e,t,":render")(r);n||E(new Error("Template not found"),e,t,":render");let l=n.content.cloneNode(!0);e.replaceChildren(l),O(e,r)},g.id=(e,t)=>{let r=j(e,t,":id");return t=>{return n=r(t),e.id=n||0===n?n:"";var n}},g.class=(e,t)=>{let r=j(e,t,":class"),n=e.getAttribute("class");return t=>{let l=r(t),s=[n];l&&("string"==typeof l?s.push(l):Array.isArray(l)?s.push(...l):s.push(...Object.entries(l).map((([e,t])=>t?e:"")))),(s=s.filter(Boolean).join(" "))?e.setAttribute("class",s):e.removeAttribute("class")}},g.style=(e,t)=>{let r=j(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=j(e,t,":text");return t=>{let n=r(t);e.textContent=null==n?"":n}},g[""]=(e,t)=>{let r=j(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=j(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))};var b=(e,t,r,n)=>{let l=n.startsWith("on")&&n.slice(2),s=j(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;const n={evt:"",target:e,test:()=>!0};n.evt=(t.startsWith("on")?t.slice(2):t).replace(/\.(\w+)?-?([-\w]+)?/g,((e,t,r="")=>(n.test=A[t]?.(n,...r.split("-"))||n.test,"")));const{evt:l,target:s,test:i,defer:o,stop:a,prevent:u,...c}=n;o&&(r=o(r));const f=e=>i(e)&&(a&&e.stopPropagation(),u&&e.preventDefault(),r.call(s,e));return s.addEventListener(l,f,c),()=>s.removeEventListener(l,f,c)},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},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 j(e,t,r){let n=S[t];if(!n)try{n=S[t]=new Function("__scope",`with (__scope) { return ${t.trim()} };`)}catch(n){return E(n,e,t,r)}return l=>{let s;try{s=n.call(e,l)}catch(n){return E(n,e,t,r)}return s}}function E(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)}O.globals=c;var N=new WeakMap;function O(e,t){if(!e.children)return;if(N.has(e))return Object.assign(N.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)),N.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],s=l.name[0];if(":"===s||"@"===s){e.removeAttribute(l.name);let t="@"===s?`event=>{${l.value}}`:l.value,i=l.name.slice(1).split(s);for(let l of i){"@"===s&&(l="on"+l);let i=g[l]||b;n.push(i(e,t,r,l))}}else 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 N.set(e,r),r}document.currentScript&&O(document.documentElement)})();
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);o.set(e,r),a.set(r,e);let n=Object.getOwnPropertyDescriptors(e);for(let t in n){let l=n[t];l.get&&l.get&&(l.get=l.get.bind(r),Object.defineProperty(e,t,l))}return 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=[j(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(j(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),O(s,e))}};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 E(new Error,e,t,":each");const n=e[m]=document.createTextNode("");e.replaceWith(n);const s=j(e,r[2],":each"),i=e.getAttribute(":key"),o=i?j(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+1,t])):Array.isArray(i)?i=i.map(((e,t)=>[t+1,e])):"object"==typeof i?i=Object.entries(i):E(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++)O(y[e],h[e])}},d.with=(e,t,r)=>{const n=j(e,t,":with")(r);O(e,p(n,r))},d.ref=(e,t,r)=>{r[t]=e},g.render=(e,t,r)=>{let n=j(e,t,":render")(r);n||E(new Error("Template not found"),e,t,":render");let l=n.content.cloneNode(!0);e.replaceChildren(l),O(e,r)},g.id=(e,t)=>{let r=j(e,t,":id");return t=>{return n=r(t),e.id=n||0===n?n:"";var n}},g.class=(e,t)=>{let r=j(e,t,":class"),n=e.getAttribute("class");return t=>{let l=r(t),s=[n];l&&("string"==typeof l?s.push(l):Array.isArray(l)?s.push(...l):s.push(...Object.entries(l).map((([e,t])=>t?e:"")))),(s=s.filter(Boolean).join(" "))?e.setAttribute("class",s):e.removeAttribute("class")}},g.style=(e,t)=>{let r=j(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=j(e,t,":text");return t=>{let n=r(t);e.textContent=null==n?"":n}},g[""]=(e,t)=>{let r=j(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=j(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))};var b=(e,t,r,n)=>{let l=n.startsWith("on")&&n.slice(2),s=j(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;const n={evt:"",target:e,test:()=>!0};n.evt=(t.startsWith("on")?t.slice(2):t).replace(/\.(\w+)?-?([-\w]+)?/g,((e,t,r="")=>(n.test=A[t]?.(n,...r.split("-"))||n.test,"")));const{evt:l,target:s,test:i,defer:o,stop:a,prevent:u,...c}=n;o&&(r=o(r));const f=e=>i(e)&&(a&&e.stopPropagation(),u&&e.preventDefault(),r.call(s,e));return s.addEventListener(l,f,c),()=>s.removeEventListener(l,f,c)},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},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 j(e,t,r){let n=S[t];if(!n)try{n=S[t]=new Function("__scope",`with (__scope) { return ${t.trim()} };`)}catch(n){return E(n,e,t,r)}return l=>{let s;try{s=n.call(e,l)}catch(n){return E(n,e,t,r)}return s}}function E(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)}O.globals=c;var N=new WeakMap;function O(e,t){if(!e.children)return;if(N.has(e))return Object.assign(N.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)),N.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],s=l.name[0];if(":"===s||"@"===s){e.removeAttribute(l.name);let t="@"===s?`${l.value.includes("await")?"async":""} event=>{${l.value}}`:l.value,i=l.name.slice(1).split(s);for(let l of i){"@"===s&&(l="on"+l);let i=g[l]||b;n.push(i(e,t,r,l))}}else 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 N.set(e,r),r}document.currentScript&&O(document.documentElement)})();
package/sprae.js CHANGED
@@ -568,7 +568,7 @@ function sprae(container, values) {
568
568
  let attr2 = el.attributes[i], prefix = attr2.name[0];
569
569
  if (prefix === ":" || prefix === "@") {
570
570
  el.removeAttribute(attr2.name);
571
- let expr = prefix === "@" ? `event=>{${attr2.value}}` : attr2.value, names = attr2.name.slice(1).split(prefix);
571
+ let expr = prefix === "@" ? `${attr2.value.includes("await") ? "async" : ""} event=>{${attr2.value}}` : attr2.value, names = attr2.name.slice(1).split(prefix);
572
572
  for (let name of names) {
573
573
  if (prefix === "@")
574
574
  name = `on` + name;
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,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);o.set(e,r),a.set(r,e);let n=Object.getOwnPropertyDescriptors(e);for(let t in n){let l=n[t];l.get&&l.get&&(l.get=l.get.bind(r),Object.defineProperty(e,t,l))}return 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=[j(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(j(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),O(s,e))}};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 E(new Error,e,t,":each");const n=e[m]=document.createTextNode("");e.replaceWith(n);const s=j(e,r[2],":each"),i=e.getAttribute(":key"),o=i?j(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+1,t])):Array.isArray(i)?i=i.map(((e,t)=>[t+1,e])):"object"==typeof i?i=Object.entries(i):E(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++)O(y[e],h[e])}},d.with=(e,t,r)=>{const n=j(e,t,":with")(r);O(e,p(n,r))},d.ref=(e,t,r)=>{r[t]=e},g.render=(e,t,r)=>{let n=j(e,t,":render")(r);n||E(new Error("Template not found"),e,t,":render");let l=n.content.cloneNode(!0);e.replaceChildren(l),O(e,r)},g.id=(e,t)=>{let r=j(e,t,":id");return t=>{return n=r(t),e.id=n||0===n?n:"";var n}},g.class=(e,t)=>{let r=j(e,t,":class"),n=e.getAttribute("class");return t=>{let l=r(t),s=[n];l&&("string"==typeof l?s.push(l):Array.isArray(l)?s.push(...l):s.push(...Object.entries(l).map((([e,t])=>t?e:"")))),(s=s.filter(Boolean).join(" "))?e.setAttribute("class",s):e.removeAttribute("class")}},g.style=(e,t)=>{let r=j(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=j(e,t,":text");return t=>{let n=r(t);e.textContent=null==n?"":n}},g[""]=(e,t)=>{let r=j(e,t,":");if(r)return t=>{let n=r(t);for(let t in n)W(e,t.replace(/[A-Z\u00C0-\u00D6\u00D8-\u00DE]/g,(e=>"-"+e.toLowerCase())),n[t])}},g.value=(e,t)=>{let r,n,l=j(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":"",W(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))};var b=(e,t,r,n)=>{let l=n.startsWith("on")&&n.slice(2),s=j(e,t,":"+n);if(s)return l?t=>{let r=s(t)||(()=>{});return v(e,l,r)}:t=>W(e,n,s(t))},v=(e,t,r)=>{if(!r)return;const n={evt:"",target:e,test:()=>!0};n.evt=(t.startsWith("on")?t.slice(2):t).replace(/\.(\w+)?-?([-\w]+)?/g,((e,t,r="")=>(n.test=A[t]?.(n,...r.split("-"))||n.test,"")));const{evt:l,target:s,test:i,defer:o,stop:a,prevent:u,...c}=n;o&&(r=o(r));const f=e=>i(e)&&(a&&e.stopPropagation(),u&&e.preventDefault(),r.call(s,e));return s.addEventListener(l,f,c),()=>s.removeEventListener(l,f,c)},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},throttle(e,t){e.defer=e=>k(e,t?Number(t)||0:108)},debounce(e,t){e.defer=e=>x(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))},x=(e,t)=>{let r;return n=>{clearTimeout(r),r=setTimeout((()=>{r=null,e(n)}),t)}},W=(e,t,r)=>{null==r||!1===r?e.removeAttribute(t):e.setAttribute(t,!0===r?"":"number"==typeof r||"string"==typeof r?r:"")},S={};function j(e,t,r){let n=S[t];if(!n)try{n=S[t]=new Function("__scope",`with (__scope) { return ${t.trim()} };`)}catch(n){return E(n,e,t,r)}return l=>{let s;try{s=n.call(e,l)}catch(n){return E(n,e,t,r)}return s}}function E(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)}O.globals=c;var N=new WeakMap;function O(e,t){if(!e.children)return;if(N.has(e))return Object.assign(N.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)),N.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],s=l.name[0];if(":"===s||"@"===s){e.removeAttribute(l.name);let t="@"===s?`event=>{${l.value}}`:l.value,i=l.name.slice(1).split(s);for(let l of i){"@"===s&&(l="on"+l);let i=g[l]||b;n.push(i(e,t,r,l))}}else 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 N.set(e,r),r}var $=O;document.currentScript&&O(document.documentElement);export{$ as default};
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);o.set(e,r),a.set(r,e);let n=Object.getOwnPropertyDescriptors(e);for(let t in n){let l=n[t];l.get&&l.get&&(l.get=l.get.bind(r),Object.defineProperty(e,t,l))}return 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=[j(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(j(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),O(s,e))}};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 E(new Error,e,t,":each");const n=e[m]=document.createTextNode("");e.replaceWith(n);const s=j(e,r[2],":each"),i=e.getAttribute(":key"),o=i?j(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+1,t])):Array.isArray(i)?i=i.map(((e,t)=>[t+1,e])):"object"==typeof i?i=Object.entries(i):E(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++)O(y[e],h[e])}},d.with=(e,t,r)=>{const n=j(e,t,":with")(r);O(e,p(n,r))},d.ref=(e,t,r)=>{r[t]=e},g.render=(e,t,r)=>{let n=j(e,t,":render")(r);n||E(new Error("Template not found"),e,t,":render");let l=n.content.cloneNode(!0);e.replaceChildren(l),O(e,r)},g.id=(e,t)=>{let r=j(e,t,":id");return t=>{return n=r(t),e.id=n||0===n?n:"";var n}},g.class=(e,t)=>{let r=j(e,t,":class"),n=e.getAttribute("class");return t=>{let l=r(t),s=[n];l&&("string"==typeof l?s.push(l):Array.isArray(l)?s.push(...l):s.push(...Object.entries(l).map((([e,t])=>t?e:"")))),(s=s.filter(Boolean).join(" "))?e.setAttribute("class",s):e.removeAttribute("class")}},g.style=(e,t)=>{let r=j(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=j(e,t,":text");return t=>{let n=r(t);e.textContent=null==n?"":n}},g[""]=(e,t)=>{let r=j(e,t,":");if(r)return t=>{let n=r(t);for(let t in n)W(e,t.replace(/[A-Z\u00C0-\u00D6\u00D8-\u00DE]/g,(e=>"-"+e.toLowerCase())),n[t])}},g.value=(e,t)=>{let r,n,l=j(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":"",W(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))};var b=(e,t,r,n)=>{let l=n.startsWith("on")&&n.slice(2),s=j(e,t,":"+n);if(s)return l?t=>{let r=s(t)||(()=>{});return v(e,l,r)}:t=>W(e,n,s(t))},v=(e,t,r)=>{if(!r)return;const n={evt:"",target:e,test:()=>!0};n.evt=(t.startsWith("on")?t.slice(2):t).replace(/\.(\w+)?-?([-\w]+)?/g,((e,t,r="")=>(n.test=A[t]?.(n,...r.split("-"))||n.test,"")));const{evt:l,target:s,test:i,defer:o,stop:a,prevent:u,...c}=n;o&&(r=o(r));const f=e=>i(e)&&(a&&e.stopPropagation(),u&&e.preventDefault(),r.call(s,e));return s.addEventListener(l,f,c),()=>s.removeEventListener(l,f,c)},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},throttle(e,t){e.defer=e=>k(e,t?Number(t)||0:108)},debounce(e,t){e.defer=e=>x(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))},x=(e,t)=>{let r;return n=>{clearTimeout(r),r=setTimeout((()=>{r=null,e(n)}),t)}},W=(e,t,r)=>{null==r||!1===r?e.removeAttribute(t):e.setAttribute(t,!0===r?"":"number"==typeof r||"string"==typeof r?r:"")},S={};function j(e,t,r){let n=S[t];if(!n)try{n=S[t]=new Function("__scope",`with (__scope) { return ${t.trim()} };`)}catch(n){return E(n,e,t,r)}return l=>{let s;try{s=n.call(e,l)}catch(n){return E(n,e,t,r)}return s}}function E(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)}O.globals=c;var N=new WeakMap;function O(e,t){if(!e.children)return;if(N.has(e))return Object.assign(N.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)),N.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],s=l.name[0];if(":"===s||"@"===s){e.removeAttribute(l.name);let t="@"===s?`${l.value.includes("await")?"async":""} event=>{${l.value}}`:l.value,i=l.name.slice(1).split(s);for(let l of i){"@"===s&&(l="on"+l);let i=g[l]||b;n.push(i(e,t,r,l))}}else 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 N.set(e,r),r}var $=O;document.currentScript&&O(document.documentElement);export{$ as default};
package/src/core.js CHANGED
@@ -1,13 +1,13 @@
1
1
  import { state as createState, fx, sandbox } from './state.js';
2
2
  import defaultDirective, { primary, secondary, on } from './directives.js';
3
3
 
4
- sprae.globals=sandbox
4
+ sprae.globals = sandbox
5
5
 
6
6
  // sprae element: apply directives
7
7
  const memo = new WeakMap
8
8
  export default function sprae(container, values) {
9
9
  if (!container.children) return
10
- if (memo.has(container)) return Object.assign( memo.get(container), values)
10
+ if (memo.has(container)) return Object.assign(memo.get(container), values)
11
11
 
12
12
  // subscribe to reactives
13
13
  // for (let prop in values) {
@@ -20,7 +20,7 @@ export default function sprae(container, values) {
20
20
  const updates = []
21
21
 
22
22
  // init directives on element
23
- const init = (el, parent=el.parentNode) => {
23
+ const init = (el, parent = el.parentNode) => {
24
24
  // init primary attributes first
25
25
  for (let name in primary) {
26
26
  let attrName = ':' + name
@@ -43,8 +43,8 @@ export default function sprae(container, values) {
43
43
 
44
44
  if (prefix === ':' || prefix === '@') {
45
45
  el.removeAttribute(attr.name)
46
- let expr = prefix === '@' ? `event=>{${attr.value}}` : attr.value,
47
- names = attr.name.slice(1).split(prefix)
46
+ let expr = prefix === '@' ? `${attr.value.includes('await') ? 'async' : ''} event=>{${attr.value}}` : attr.value,
47
+ names = attr.name.slice(1).split(prefix)
48
48
 
49
49
  // multiple attributes like :id:for="" or @click@touchstart
50
50
  for (let name of names) {
package/src/directives.js CHANGED
@@ -2,21 +2,20 @@
2
2
  import sprae from './core.js'
3
3
  import swap from './domdiff.js'
4
4
  // import swap from 'swapdom'
5
- import { state as createState} from './state.js'
5
+ import { state as createState } from './state.js'
6
6
  import { queueMicrotask, WeakishMap } from './util.js'
7
7
 
8
8
  // reserved directives - order matters!
9
9
  // primary initialized first by selector, secondary initialized by iterating attributes
10
10
  export const primary = {}, secondary = {}
11
11
 
12
-
13
12
  // :if is interchangeable with :each depending on order, :if :each or :each :if have different meanings
14
13
  // as for :if :with - :if must init first, since it is lazy, to avoid initializing component ahead of time by :with
15
14
  // we consider :with={x} :if={x} case insignificant
16
15
  primary['if'] = (el, expr) => {
17
16
  let holder = document.createTextNode(''),
18
- clauses = [parseExpr(el, expr, ':if')],
19
- els = [el], cur = el
17
+ clauses = [parseExpr(el, expr, ':if')],
18
+ els = [el], cur = el
20
19
 
21
20
  while (cur = el.nextElementSibling) {
22
21
  if (cur.hasAttribute(':else')) {
@@ -37,7 +36,7 @@ primary['if'] = (el, expr) => {
37
36
  return (state) => {
38
37
  let i = clauses.findIndex(f => f(state))
39
38
  if (els[i] != cur) {
40
- ;(cur[_each] || cur).replaceWith(cur = els[i] || holder);
39
+ ; (cur[_each] || cur).replaceWith(cur = els[i] || holder);
41
40
  // NOTE: it lazily initializes elements on insertion, it's safe to sprae multiple times
42
41
  // but :if must come first to avoid preliminary caching
43
42
  sprae(cur, state);
@@ -74,8 +73,8 @@ primary['each'] = (tpl, expr) => {
74
73
  let list = evaluate(state)
75
74
 
76
75
  if (!list) list = []
77
- else if (typeof list === 'number') list = Array.from({length: list}, (_, i)=>[i+1, i])
78
- else if (Array.isArray(list)) list = list.map((item,i) => [i+1, item])
76
+ else if (typeof list === 'number') list = Array.from({ length: list }, (_, i) => [i + 1, i])
77
+ else if (Array.isArray(list)) list = list.map((item, i) => [i + 1, item])
79
78
  else if (typeof list === 'object') list = Object.entries(list)
80
79
  else exprError(Error('Bad list value'), tpl, expr, ':each', list)
81
80
 
@@ -83,7 +82,7 @@ primary['each'] = (tpl, expr) => {
83
82
  let newEls = [], elScopes = []
84
83
 
85
84
  for (let [idx, item] of list) {
86
- let el, scope, key = itemKey?.({[each[0]]: item, [each[1]]: idx})
85
+ let el, scope, key = itemKey?.({ [each[0]]: item, [each[1]]: idx })
87
86
 
88
87
  // we consider if data items are primitive, then nodes needn't be cached
89
88
  // since likely they're very simple to create
@@ -93,7 +92,7 @@ primary['each'] = (tpl, expr) => {
93
92
  newEls.push(el)
94
93
 
95
94
  if (key == null || !(scope = scopes.get(key))) {
96
- scope = createState({[each[0]]: item, [refExpr||'']: null, [each[1]]: idx}, state)
95
+ scope = createState({ [each[0]]: item, [refExpr || '']: null, [each[1]]: idx }, state)
97
96
  if (key != null) scopes.set(key, scope)
98
97
  }
99
98
  // need to explicitly set item to update existing children's values
@@ -153,7 +152,7 @@ function parseForExpression(expression) {
153
152
 
154
153
  secondary['render'] = (el, expr, state) => {
155
154
  let evaluate = parseExpr(el, expr, ':render'),
156
- tpl = evaluate(state)
155
+ tpl = evaluate(state)
157
156
 
158
157
  if (!tpl) exprError(new Error('Template not found'), el, expr, ':render');
159
158
 
@@ -177,7 +176,7 @@ secondary['class'] = (el, expr) => {
177
176
  if (v) {
178
177
  if (typeof v === 'string') className.push(v)
179
178
  else if (Array.isArray(v)) className.push(...v)
180
- else className.push(...Object.entries(v).map(([k,v])=>v?k:''))
179
+ else className.push(...Object.entries(v).map(([k, v]) => v ? k : ''))
181
180
  }
182
181
  if (className = className.filter(Boolean).join(' ')) el.setAttribute('class', className);
183
182
  else el.removeAttribute('class')
@@ -222,19 +221,19 @@ secondary['value'] = (el, expr) => {
222
221
  let from, to
223
222
  let update = (
224
223
  el.type === 'text' || el.type === '' ? value => el.setAttribute('value', el.value = value == null ? '' : value) :
225
- el.tagName === 'TEXTAREA' || el.type === 'text' || el.type === '' ? value => (
226
- // we retain selection in input
227
- from = el.selectionStart, to = el.selectionEnd,
228
- el.setAttribute('value', el.value = value == null ? '' : value),
229
- from && el.setSelectionRange(from, to)
230
- ) :
231
- el.type === 'checkbox' ? value => (el.value = value ? 'on' : '', attr(el, 'checked', value)) :
232
- el.type === 'select-one' ? value => {
233
- for (let option in el.options) option.removeAttribute('selected')
234
- el.value = value;
235
- el.selectedOptions[0]?.setAttribute('selected', '')
236
- } :
237
- value => el.value = value
224
+ el.tagName === 'TEXTAREA' || el.type === 'text' || el.type === '' ? value => (
225
+ // we retain selection in input
226
+ from = el.selectionStart, to = el.selectionEnd,
227
+ el.setAttribute('value', el.value = value == null ? '' : value),
228
+ from && el.setSelectionRange(from, to)
229
+ ) :
230
+ el.type === 'checkbox' ? value => (el.value = value ? 'on' : '', attr(el, 'checked', value)) :
231
+ el.type === 'select-one' ? value => {
232
+ for (let option in el.options) option.removeAttribute('selected')
233
+ el.value = value;
234
+ el.selectedOptions[0]?.setAttribute('selected', '')
235
+ } :
236
+ value => el.value = value
238
237
  )
239
238
 
240
239
  return (state) => update(evaluate(state))
@@ -243,13 +242,13 @@ secondary['value'] = (el, expr) => {
243
242
  // any unknown directive
244
243
  export default (el, expr, state, name) => {
245
244
  let evt = name.startsWith('on') && name.slice(2)
246
- let evaluate = parseExpr(el, expr, ':'+name)
245
+ let evaluate = parseExpr(el, expr, ':' + name)
247
246
 
248
247
  if (!evaluate) return
249
248
 
250
249
  if (evt) return (state => {
251
250
  // we need anonymous callback to enable modifiers like prevent
252
- let value = evaluate(state) || (()=>{})
251
+ let value = evaluate(state) || (() => { })
253
252
  return on(el, evt, value)
254
253
  })
255
254
 
@@ -260,21 +259,21 @@ export default (el, expr, state, name) => {
260
259
  export const on = (el, e, fn) => {
261
260
  if (!fn) return
262
261
 
263
- const ctx = { evt:'', target:el, test:()=>true };
262
+ const ctx = { evt: '', target: el, test: () => true };
264
263
 
265
264
  // onevt.debounce-108 -> evt.debounce-108
266
265
  ctx.evt = (e.startsWith('on') ? e.slice(2) : e).replace(/\.(\w+)?-?([-\w]+)?/g,
267
- (match, mod, param='') => (ctx.test = mods[mod]?.(ctx, ...param.split('-')) || ctx.test, '')
266
+ (match, mod, param = '') => (ctx.test = mods[mod]?.(ctx, ...param.split('-')) || ctx.test, '')
268
267
  );
269
268
 
270
269
  // add listener applying the context
271
- const {evt, target, test, defer, stop, prevent, ...opts} = ctx;
270
+ const { evt, target, test, defer, stop, prevent, ...opts } = ctx;
272
271
 
273
272
  if (defer) fn = defer(fn)
274
273
 
275
274
  const cb = e => test(e) && (
276
- stop&&e.stopPropagation(),
277
- prevent&&e.preventDefault(),
275
+ stop && e.stopPropagation(),
276
+ prevent && e.preventDefault(),
278
277
  fn.call(target, e)
279
278
  )
280
279
 
@@ -365,7 +364,7 @@ const debounce = (fn, wait) => {
365
364
  let timeout
366
365
  return (e) => {
367
366
  clearTimeout(timeout)
368
- timeout = setTimeout(() => {timeout = null; fn(e)}, wait)
367
+ timeout = setTimeout(() => { timeout = null; fn(e) }, wait)
369
368
  }
370
369
  }
371
370
 
@@ -385,8 +384,8 @@ function parseExpr(el, expression, dir) {
385
384
 
386
385
  if (!evaluate) {
387
386
  try {
388
- evaluate = evaluatorMemo[expression] = new Function(`__scope`,`with (__scope) { return ${expression.trim()} };`)
389
- } catch ( e ) {
387
+ evaluate = evaluatorMemo[expression] = new Function(`__scope`, `with (__scope) { return ${expression.trim()} };`)
388
+ } catch (e) {
390
389
  return exprError(e, el, expression, dir)
391
390
  }
392
391
  }
@@ -401,11 +400,11 @@ function parseExpr(el, expression, dir) {
401
400
  }
402
401
 
403
402
  function exprError(error, element, expression, directive) {
404
- Object.assign( error, { element, expression } )
405
- console.warn(`∴ ${error.message}\n\n${directive}=${ expression ? `"${expression}"\n\n` : '' }`, element)
403
+ Object.assign(error, { element, expression })
404
+ console.warn(`∴ ${error.message}\n\n${directive}=${expression ? `"${expression}"\n\n` : ''}`, element)
406
405
  queueMicrotask(() => { throw error }, 0)
407
406
  }
408
407
 
409
408
  function dashcase(str) {
410
- return str.replace(/[A-Z\u00C0-\u00D6\u00D8-\u00DE]/g, (match) => '-' + match.toLowerCase());
409
+ return str.replace(/[A-Z\u00C0-\u00D6\u00D8-\u00DE]/g, (match) => '-' + match.toLowerCase());
411
410
  };
package/.gitattributes DELETED
@@ -1,2 +0,0 @@
1
- # Auto detect text files and perform LF normalization
2
- * text=auto