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 +7 -0
- package/package.json +9 -2
- package/readme.md +67 -47
- package/sprae.auto.js +1 -1
- package/sprae.auto.min.js +1 -1
- package/sprae.js +1 -1
- package/sprae.min.js +1 -1
- package/src/core.js +5 -5
- package/src/directives.js +36 -37
- package/.gitattributes +0 -2
- package/.github/workflows/node.js.yml +0 -30
- package/examples/todomvc.html +0 -98
- package/r&d.md +0 -620
- package/test/attrs.js +0 -754
- package/test/events.js +0 -138
- package/test/index.html +0 -36
- package/test/register.cjs +0 -20
- package/test/state.js +0 -296
- package/test/test.js +0 -13
- package/todo.md +0 -54
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.
|
|
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": "
|
|
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æ [](https://github.com/dy/sprae/actions/workflows/node.js.yml) [](https://bundlephobia.com/result?p=sprae) [](https://npmjs.org/sprae)
|
|
2
2
|
|
|
3
|
-
> DOM
|
|
3
|
+
> DOM tree hydration with reactivity.
|
|
4
4
|
|
|
5
|
-
_Sprae_ is
|
|
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
|
-
<
|
|
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
|
|
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.
|
|
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: {
|
|
34
|
-
state.user.
|
|
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
|
|
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.
|
|
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
|
-
<!--
|
|
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
|
-
|
|
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
|
-
|
|
112
|
-
<
|
|
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
|
-
####
|
|
148
|
+
#### `:<prop>="value?"`
|
|
137
149
|
|
|
138
|
-
|
|
150
|
+
Set any attribute value or run an effect.
|
|
139
151
|
|
|
140
152
|
```html
|
|
141
|
-
|
|
153
|
+
<!-- Single property -->
|
|
154
|
+
<label :for="name" :text="name" />
|
|
142
155
|
|
|
143
|
-
|
|
144
|
-
<
|
|
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
|
-
####
|
|
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
|
-
|
|
193
|
+
Include template as element content.
|
|
175
194
|
|
|
176
195
|
```html
|
|
177
|
-
<!--
|
|
178
|
-
<
|
|
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
|
-
<!--
|
|
187
|
-
<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.
|
|
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="
|
|
225
|
-
<!--
|
|
238
|
+
<div :x="scrollY"></div>
|
|
239
|
+
<!-- scrollY is undefined -->
|
|
226
240
|
```
|
|
227
241
|
|
|
228
|
-
Default sandbox provides: _window_, _document_, _console_, _history_, _location_,
|
|
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)
|
|
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 === "@" ?
|
|
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
|
|
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 === "@" ?
|
|
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
|
|
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(
|
|
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 === '@' ?
|
|
47
|
-
|
|
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
|
-
|
|
19
|
-
|
|
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
|
-
|
|
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
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
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
|
|
389
|
-
} catch (
|
|
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(
|
|
405
|
-
console.warn(`∴ ${error.message}\n\n${directive}=${
|
|
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
|
-
|
|
409
|
+
return str.replace(/[A-Z\u00C0-\u00D6\u00D8-\u00DE]/g, (match) => '-' + match.toLowerCase());
|
|
411
410
|
};
|
package/.gitattributes
DELETED