sprae 2.7.1 → 2.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +2 -2
- package/r&d.md +62 -14
- package/readme.md +19 -4
- package/sprae.js +186 -61
- package/sprae.min.js +1 -1
- package/src/directives.js +116 -43
- package/test/test.js +58 -3
- package/todo.md +4 -1
package/package.json
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "sprae",
|
|
3
3
|
"description": "DOM microhydration.",
|
|
4
|
-
"version": "2.
|
|
4
|
+
"version": "2.8.0",
|
|
5
5
|
"main": "src/index.js",
|
|
6
6
|
"module": "src/index.js",
|
|
7
7
|
"type": "module",
|
|
8
8
|
"dependencies": {
|
|
9
9
|
"@preact/signals-core": "^1.2.2",
|
|
10
10
|
"primitive-pool": "^2.0.0",
|
|
11
|
-
"signal-struct": "^1.
|
|
11
|
+
"signal-struct": "^1.10.0",
|
|
12
12
|
"swapdom": "^1.1.1"
|
|
13
13
|
},
|
|
14
14
|
"devDependencies": {
|
package/r&d.md
CHANGED
|
@@ -289,9 +289,9 @@
|
|
|
289
289
|
* @sprae/item: `<x :item="{type:a, scope:b}"` – provide microdata
|
|
290
290
|
- can be solved naturally, unless there's special meaning
|
|
291
291
|
* @sprae/hcodes: `<x :hcode=""` – provide microformats
|
|
292
|
-
* @sprae/with
|
|
293
|
-
* @sprae/onconnected
|
|
294
292
|
* @sprae/onvisible?
|
|
293
|
+
- can be solved externally
|
|
294
|
+
* @sprae/onintersects
|
|
295
295
|
|
|
296
296
|
## [x] Write any-attributes via `:<prop>? -> yep`
|
|
297
297
|
|
|
@@ -330,7 +330,7 @@
|
|
|
330
330
|
+ Provides precisely controlled sandbox
|
|
331
331
|
- Some limited lang opportunities
|
|
332
332
|
- need to match many syntax quirks, can be tedious
|
|
333
|
-
~ can be fine to limit expressions to meaningful default:
|
|
333
|
+
~ can be fine to limit expressions to meaningful default: no Proxy, generators, awaits, global access etc.
|
|
334
334
|
- Somewhat heavy to bundle
|
|
335
335
|
~ 1-2kb is not super-heavy, besides kicks out signal-struct (with preact signals?)
|
|
336
336
|
+ Scope is easier to provide: no need for signal proxy
|
|
@@ -340,6 +340,7 @@
|
|
|
340
340
|
+ Deps can be analyzed / implemented without signals
|
|
341
341
|
- Screwed up debugging / stacktrace (unless errored properly)
|
|
342
342
|
~+ can actually provide better trace since no internal framework stuff is shown
|
|
343
|
+
+ can let means to enhance subscript's logs
|
|
343
344
|
+ that "unlimits" returned struct, so that any property can be added/deleted.
|
|
344
345
|
- doesn't really save from `new (()=>{}).constructor` hack: we gotta substitute objects too.
|
|
345
346
|
+ allows easier handle of `:with="a=1,b=2,c=3"` - we just naturally get local variables without messup with global
|
|
@@ -349,9 +350,10 @@
|
|
|
349
350
|
|
|
350
351
|
2. Use sandboxed proxy
|
|
351
352
|
- tough evaluation
|
|
352
|
-
-
|
|
353
|
+
- implementation hiccups
|
|
353
354
|
- screwed up data
|
|
354
355
|
- no full protection
|
|
356
|
+
- relatively slow
|
|
355
357
|
+ does minimal catch
|
|
356
358
|
|
|
357
359
|
## [x] :onclick="direct code" ? -> no: immediately invoked.
|
|
@@ -374,19 +376,23 @@
|
|
|
374
376
|
? maybe id should have same signature
|
|
375
377
|
? should it be very similar mechanism to `:with="a=1,b=2"`
|
|
376
378
|
|
|
377
|
-
## [
|
|
379
|
+
## [x] Event modifiers :ona.once, `:ona` -> let's try, there's a lot of use for both props and event
|
|
378
380
|
|
|
379
381
|
- .prevent,.stop - not needed since expects a function
|
|
380
382
|
? or should we just trigger it for user?
|
|
381
383
|
? :onclick.outside
|
|
382
384
|
? :onclick.window, :onclick.document
|
|
383
|
-
|
|
384
|
-
? :onclick.
|
|
385
|
-
|
|
385
|
+
+ can be needed, eg. mousedown..up can happen outside of current element (stop caret tracking in waveplay)
|
|
386
|
+
? :onclick.once, :onclick.passive, :onclick.capture
|
|
387
|
+
+ can pass props to event listener: there's no other way to do that
|
|
388
|
+
? :onclick.debounce-330
|
|
389
|
+
? :onclick.throttle-750
|
|
390
|
+
+ ...just handy everydayers and saves tons of noise
|
|
386
391
|
? :onclick.self
|
|
392
|
+
~ clicked on self, not the child
|
|
387
393
|
? :onspecial-event.camel, :onx-y.dot
|
|
388
|
-
|
|
389
|
-
? :onkeypress.shift.enter
|
|
394
|
+
~
|
|
395
|
+
? :onkeypress.shift.enter, :onmousemove.shift, :onmousemove.alt
|
|
390
396
|
.shift Shift
|
|
391
397
|
.enter Enter
|
|
392
398
|
.space Space
|
|
@@ -394,15 +400,57 @@
|
|
|
394
400
|
.cmd Cmd
|
|
395
401
|
.meta Cmd on Mac, Windows key on Windows
|
|
396
402
|
.alt Alt
|
|
397
|
-
.up .down .left .right
|
|
403
|
+
.up .down .left .right
|
|
398
404
|
.escape Escape
|
|
399
405
|
.tab Tab
|
|
400
406
|
.caps-lock Caps Lock
|
|
401
|
-
.equal Equal
|
|
402
|
-
.period Period
|
|
403
|
-
.slash Foward Slash
|
|
407
|
+
.equal Equal
|
|
408
|
+
.period Period
|
|
409
|
+
.slash Foward Slash
|
|
410
|
+
+ allows separating various key handlers: atm waveplay handles separate keys in the same method `handleKey`
|
|
411
|
+
+ allows tracking mouse interactions with shift hold
|
|
404
412
|
- conflict with dot-separated events
|
|
413
|
+
~not so popular nor encouraged
|
|
405
414
|
- lots of ad-hoc non-standard rules, can be handled in code
|
|
415
|
+
+ allow multiple setters for same props or multiple listeners for same events
|
|
416
|
+
+ oldschool jquery-compatible events
|
|
417
|
+
|
|
418
|
+
## [x] Mods design -> use event modifiers, not props modifiers
|
|
419
|
+
|
|
420
|
+
* [ ] ~~Prop modifiers~~
|
|
421
|
+
- overall seems code complication without much benefit
|
|
422
|
+
* [ ] value.bind? value.watch?
|
|
423
|
+
- let's wait for use-case: value can be too big to set it every time
|
|
424
|
+
* [ ] prop.reflect, prop.observe
|
|
425
|
+
- let's wait for use-case
|
|
426
|
+
* [ ] prop.boolean, .number, .string, .array, .object
|
|
427
|
+
- let's wait for use-case
|
|
428
|
+
* [ ] prop.once, prop.fx ? prop.init?
|
|
429
|
+
- doesn't seem required, let's wait for use case
|
|
430
|
+
* [ ] prop.change - run only if value changes
|
|
431
|
+
- seems like unnecessary manual optimization that must be done always automatically
|
|
432
|
+
? are there cases where force-update is necessary?
|
|
433
|
+
* [ ] prop.throttle-xxx, prop.debounce-xxx
|
|
434
|
+
- let's wait until that's really a problem
|
|
435
|
+
* [ ] prop.class
|
|
436
|
+
? what's the use-case
|
|
437
|
+
|
|
438
|
+
* [x] Event modifiers
|
|
439
|
+
* [x] onevt.x, onevt.y
|
|
440
|
+
+ jquery-like
|
|
441
|
+
+ multiple same events
|
|
442
|
+
* [x] onevt.once, onevt.passive, onevt.capture
|
|
443
|
+
+ standard props passing
|
|
444
|
+
* [x] onevt.prevent, onevt.stop
|
|
445
|
+
+ conventional mods
|
|
446
|
+
* [x] onevt.outside onevt.window, onevt.document, onevt.self
|
|
447
|
+
+ useful handlers, conventional mods
|
|
448
|
+
* [x] onevt.throttle-xxx, onevt.debounce-xxx
|
|
449
|
+
+ conventional
|
|
450
|
+
* [x] onevt.shift, onevt.cmd.shift, onevt.meta
|
|
451
|
+
+ conventional
|
|
452
|
+
* [x] onkey.enter, .space, .up|.down|.left|.right, .escape, .tab, .period, .slash, .caps-lock
|
|
453
|
+
+ conventional
|
|
406
454
|
|
|
407
455
|
## [x] Writing props on elements (like ones in :each) -> nah, just use `:x="this.x=abc"`
|
|
408
456
|
|
package/readme.md
CHANGED
|
@@ -2,9 +2,6 @@
|
|
|
2
2
|
|
|
3
3
|
> DOM microhydration with `:` attributes
|
|
4
4
|
|
|
5
|
-
A lightweight essential alternative to [alpine](https://github.com/alpinejs/alpine), [petite-vue](https://github.com/vuejs/petite-vue), [templize](https://github.com/dy/templize) or JSX with better ergonomics[*](#justification).<br>
|
|
6
|
-
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.
|
|
7
|
-
|
|
8
5
|
|
|
9
6
|
## Usage
|
|
10
7
|
|
|
@@ -163,10 +160,22 @@ Add event listeners.
|
|
|
163
160
|
}
|
|
164
161
|
}">
|
|
165
162
|
|
|
163
|
+
<!-- Event modifiers -->
|
|
164
|
+
<button :onclick.throttle-500="handler">Not too often</button>
|
|
165
|
+
|
|
166
166
|
<!-- Bulk/custom events -->
|
|
167
167
|
<button :on="{ click: handler, touch: handler, special: handler }">Submit</button>
|
|
168
168
|
```
|
|
169
169
|
|
|
170
|
+
##### Event modifiers
|
|
171
|
+
|
|
172
|
+
* `.once`, `.passive`, `.capture` – listener [options](https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener#options).
|
|
173
|
+
* `.prevent`, `.stop` – prevent default or stop propagation.
|
|
174
|
+
* `.window`, `.document`, `.outside`, `.self` – specify event target.
|
|
175
|
+
* `.throttle-108`, `.debounce-108` – define throttling or postponing callback with (optional) timeout in ms.
|
|
176
|
+
* `.ctrl`, `.shift`, `.alt`, `.meta`, `.cmd`, `.down`, `.up`, `.left`, `.right`, `.end`, `.home`, `.pagedown`, `.pageup`, `.enter`, `.plus`, `.minus`, `.star`, `.slash`, `.period`, `.equal`, `.underscore`, `.esc`, `.escape`, `.tab`, `.space`, `.backspace`, `.delete` – filter by [`event.key`](https://developer.mozilla.org/en-US/docs/Web/API/UI_Events/Keyboard_event_key_values).
|
|
177
|
+
* `.*` – any other modifier has no effect, but allows binding multiple handlers to same event (like jQuery event classes).
|
|
178
|
+
|
|
170
179
|
#### `:data="values"`
|
|
171
180
|
|
|
172
181
|
Set [data-*](https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/data-*) attributes. CamelCase is converted to dash-case.
|
|
@@ -334,11 +343,13 @@ This way, for example, _@preact/signals_ or _rxjs_ can be connected directly byp
|
|
|
334
343
|
|
|
335
344
|
## Justification
|
|
336
345
|
|
|
346
|
+
_Sprae_ is lightweight essential alternative to [alpine](https://github.com/alpinejs/alpine), [petite-vue](https://github.com/vuejs/petite-vue), [templize](https://github.com/dy/templize) or JSX with better ergonomics[*](#justification).
|
|
347
|
+
|
|
337
348
|
* [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.
|
|
338
349
|
* [Alpine](https://github.com/alpinejs/alpine) / [vue](https://github.com/vuejs/petite-vue) / [lit](https://github.com/lit/lit/tree/main/packages/lit-html) escapes native HTML quirks, but the syntax is a bit scattered: `:attr`, `v-*`,`x-*`, `@evt`, `{{}}` can be expressed with single convention. Besides, functionality is too broad and can be reduced to essence: perfection is when there's nothing to take away, not add. Also they tend to [self-encapsulate](https://github.com/alpinejs/alpine/discussions/3223), making interop hard.
|
|
339
350
|
* 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).
|
|
340
351
|
|
|
341
|
-
|
|
352
|
+
_Sprae_ takes convention of _templize directives_ (_alpine_/_vue_ attrs) and builds upon [_@preact/signals_](https://ghub.io/@preact/signals).
|
|
342
353
|
|
|
343
354
|
* It doesn't break static html markup.
|
|
344
355
|
* It falls back to element content if uninitialized.
|
|
@@ -349,4 +360,8 @@ _sprae_ takes convention of _templize directives_ (_alpine_/_vue_ attrs) and bui
|
|
|
349
360
|
* Input data may contain [signals](https://ghub.io/@preact/signals) or [reactive values](https://ghub.io/sube).
|
|
350
361
|
* Elements / data API is open and enable easy interop.
|
|
351
362
|
|
|
363
|
+
|
|
364
|
+
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.
|
|
365
|
+
|
|
366
|
+
|
|
352
367
|
<p align="center"><a href="https://github.com/krsnzd/license/">🕉</a></p>
|
package/sprae.js
CHANGED
|
@@ -71,16 +71,16 @@ function v(i2) {
|
|
|
71
71
|
}
|
|
72
72
|
}
|
|
73
73
|
}
|
|
74
|
-
function
|
|
74
|
+
function e2(i2) {
|
|
75
75
|
this.v = i2;
|
|
76
76
|
this.i = 0;
|
|
77
77
|
this.n = void 0;
|
|
78
78
|
this.t = void 0;
|
|
79
79
|
}
|
|
80
|
-
|
|
80
|
+
e2.prototype.h = function() {
|
|
81
81
|
return true;
|
|
82
82
|
};
|
|
83
|
-
|
|
83
|
+
e2.prototype.S = function(i2) {
|
|
84
84
|
if (this.t !== i2 && void 0 === i2.e) {
|
|
85
85
|
i2.x = this.t;
|
|
86
86
|
if (void 0 !== this.t)
|
|
@@ -88,7 +88,7 @@ e.prototype.S = function(i2) {
|
|
|
88
88
|
this.t = i2;
|
|
89
89
|
}
|
|
90
90
|
};
|
|
91
|
-
|
|
91
|
+
e2.prototype.U = function(i2) {
|
|
92
92
|
var t2 = i2.e, h2 = i2.x;
|
|
93
93
|
if (void 0 !== t2) {
|
|
94
94
|
t2.x = h2;
|
|
@@ -101,7 +101,7 @@ e.prototype.U = function(i2) {
|
|
|
101
101
|
if (i2 === this.t)
|
|
102
102
|
this.t = h2;
|
|
103
103
|
};
|
|
104
|
-
|
|
104
|
+
e2.prototype.subscribe = function(i2) {
|
|
105
105
|
var t2 = this;
|
|
106
106
|
return b(function() {
|
|
107
107
|
var h2 = t2.value, o2 = 32 & this.f;
|
|
@@ -113,16 +113,16 @@ e.prototype.subscribe = function(i2) {
|
|
|
113
113
|
}
|
|
114
114
|
});
|
|
115
115
|
};
|
|
116
|
-
|
|
116
|
+
e2.prototype.valueOf = function() {
|
|
117
117
|
return this.value;
|
|
118
118
|
};
|
|
119
|
-
|
|
119
|
+
e2.prototype.toString = function() {
|
|
120
120
|
return this.value + "";
|
|
121
121
|
};
|
|
122
|
-
|
|
122
|
+
e2.prototype.peek = function() {
|
|
123
123
|
return this.v;
|
|
124
124
|
};
|
|
125
|
-
Object.defineProperty(
|
|
125
|
+
Object.defineProperty(e2.prototype, "value", { get: function() {
|
|
126
126
|
var i2 = v(this);
|
|
127
127
|
if (void 0 !== i2)
|
|
128
128
|
i2.i = this.i;
|
|
@@ -144,7 +144,7 @@ Object.defineProperty(e.prototype, "value", { get: function() {
|
|
|
144
144
|
}
|
|
145
145
|
} });
|
|
146
146
|
function u(i2) {
|
|
147
|
-
return new
|
|
147
|
+
return new e2(i2);
|
|
148
148
|
}
|
|
149
149
|
function d(i2) {
|
|
150
150
|
for (var t2 = i2.s; void 0 !== t2; t2 = t2.n)
|
|
@@ -183,13 +183,13 @@ function a(i2) {
|
|
|
183
183
|
i2.s = h2;
|
|
184
184
|
}
|
|
185
185
|
function l(i2) {
|
|
186
|
-
|
|
186
|
+
e2.call(this, void 0);
|
|
187
187
|
this.x = i2;
|
|
188
188
|
this.s = void 0;
|
|
189
189
|
this.g = f - 1;
|
|
190
190
|
this.f = 4;
|
|
191
191
|
}
|
|
192
|
-
(l.prototype = new
|
|
192
|
+
(l.prototype = new e2()).h = function() {
|
|
193
193
|
this.f &= -3;
|
|
194
194
|
if (1 & this.f)
|
|
195
195
|
return false;
|
|
@@ -230,10 +230,10 @@ l.prototype.S = function(i2) {
|
|
|
230
230
|
for (var t2 = this.s; void 0 !== t2; t2 = t2.n)
|
|
231
231
|
t2.S.S(t2);
|
|
232
232
|
}
|
|
233
|
-
|
|
233
|
+
e2.prototype.S.call(this, i2);
|
|
234
234
|
};
|
|
235
235
|
l.prototype.U = function(i2) {
|
|
236
|
-
|
|
236
|
+
e2.prototype.U.call(this, i2);
|
|
237
237
|
if (void 0 === this.t) {
|
|
238
238
|
this.f &= -33;
|
|
239
239
|
for (var t2 = this.s; void 0 !== t2; t2 = t2.n)
|
|
@@ -408,7 +408,7 @@ function signalStruct(values, proto) {
|
|
|
408
408
|
try {
|
|
409
409
|
Object.assign(s2.value, v2);
|
|
410
410
|
return;
|
|
411
|
-
} catch (
|
|
411
|
+
} catch (e3) {
|
|
412
412
|
}
|
|
413
413
|
s2.value = Object.seal(signalStruct(v2));
|
|
414
414
|
} else if (Array.isArray(v2))
|
|
@@ -425,7 +425,8 @@ function signalStruct(values, proto) {
|
|
|
425
425
|
return state;
|
|
426
426
|
}
|
|
427
427
|
if (Array.isArray(values) && !isStruct(values[0])) {
|
|
428
|
-
|
|
428
|
+
for (let i2 = 0; i2 < values.length; i2++)
|
|
429
|
+
values[i2] = signalStruct(values[i2]);
|
|
429
430
|
}
|
|
430
431
|
return values;
|
|
431
432
|
}
|
|
@@ -623,6 +624,31 @@ secondary["text"] = (el, expr) => {
|
|
|
623
624
|
el.textContent = value == null ? "" : value;
|
|
624
625
|
};
|
|
625
626
|
};
|
|
627
|
+
secondary["data"] = (el, expr) => {
|
|
628
|
+
let evaluate = parseExpr(el, expr, ":data");
|
|
629
|
+
return (state) => {
|
|
630
|
+
let value = evaluate(state);
|
|
631
|
+
for (let key in value)
|
|
632
|
+
el.dataset[key] = value[key];
|
|
633
|
+
};
|
|
634
|
+
};
|
|
635
|
+
secondary["aria"] = (el, expr) => {
|
|
636
|
+
let evaluate = parseExpr(el, expr, ":aria");
|
|
637
|
+
const update = (value) => {
|
|
638
|
+
for (let key in value)
|
|
639
|
+
attr(el, "aria-" + dashcase(key), value[key] == null ? null : value[key] + "");
|
|
640
|
+
};
|
|
641
|
+
return (state) => update(evaluate(state));
|
|
642
|
+
};
|
|
643
|
+
secondary[""] = (el, expr) => {
|
|
644
|
+
let evaluate = parseExpr(el, expr, ":");
|
|
645
|
+
if (evaluate)
|
|
646
|
+
return (state) => {
|
|
647
|
+
let value = evaluate(state);
|
|
648
|
+
for (let key in value)
|
|
649
|
+
attr(el, dashcase(key), value[key]);
|
|
650
|
+
};
|
|
651
|
+
};
|
|
626
652
|
secondary["value"] = (el, expr) => {
|
|
627
653
|
let evaluate = parseExpr(el, expr, ":value");
|
|
628
654
|
let from, to;
|
|
@@ -646,16 +672,35 @@ secondary["on"] = (el, expr) => {
|
|
|
646
672
|
};
|
|
647
673
|
};
|
|
648
674
|
};
|
|
675
|
+
var directives_default = (el, expr, state, name) => {
|
|
676
|
+
let evt = name.startsWith("on") && name.slice(2);
|
|
677
|
+
let evaluate = parseExpr(el, expr, ":" + name);
|
|
678
|
+
if (!evaluate)
|
|
679
|
+
return;
|
|
680
|
+
if (evt)
|
|
681
|
+
return (state2) => {
|
|
682
|
+
let value = evaluate(state2);
|
|
683
|
+
if (value) {
|
|
684
|
+
addListener(el, evt, value);
|
|
685
|
+
return () => removeListener(el, evt, value);
|
|
686
|
+
}
|
|
687
|
+
};
|
|
688
|
+
return (state2) => attr(el, name, evaluate(state2));
|
|
689
|
+
};
|
|
649
690
|
var _stop = Symbol("stop");
|
|
650
691
|
var addListener = (el, evt, startFn) => {
|
|
651
|
-
|
|
652
|
-
|
|
692
|
+
let evts = evt.split("..").map((e3) => e3.startsWith("on") ? e3.slice(2) : e3), opts = {};
|
|
693
|
+
evts[0] = evts[0].replace(
|
|
694
|
+
/\.(\w+)?-?([\w]+)?/g,
|
|
695
|
+
(match, mod, param) => (mod = mods[mod]) ? ([el, startFn] = mod(el, startFn, opts, param), "") : ""
|
|
696
|
+
);
|
|
697
|
+
if (evts.length == 1)
|
|
698
|
+
el.addEventListener(evts[0], startFn, opts);
|
|
653
699
|
else {
|
|
654
|
-
const evts = evt.split("..").map((e2) => e2.startsWith("on") ? e2.slice(2) : e2);
|
|
655
700
|
const nextEvt = (fn, cur = 0) => {
|
|
656
|
-
let curListener = (
|
|
701
|
+
let curListener = (e3) => {
|
|
657
702
|
el.removeEventListener(evts[cur], curListener);
|
|
658
|
-
if (typeof (fn = fn.call(el,
|
|
703
|
+
if (typeof (fn = fn.call(el, e3)) !== "function")
|
|
659
704
|
fn = () => {
|
|
660
705
|
};
|
|
661
706
|
if (++cur < evts.length)
|
|
@@ -663,7 +708,7 @@ var addListener = (el, evt, startFn) => {
|
|
|
663
708
|
else if (!startFn[_stop])
|
|
664
709
|
nextEvt(startFn);
|
|
665
710
|
};
|
|
666
|
-
el.addEventListener(evts[cur], curListener);
|
|
711
|
+
el.addEventListener(evts[cur], curListener, opts);
|
|
667
712
|
};
|
|
668
713
|
nextEvt(startFn);
|
|
669
714
|
}
|
|
@@ -673,43 +718,123 @@ var removeListener = (el, evt, fn) => {
|
|
|
673
718
|
fn[_stop] = true;
|
|
674
719
|
el.removeEventListener(evt, fn);
|
|
675
720
|
};
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
let
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
const update = (value) => {
|
|
687
|
-
for (let key in value)
|
|
688
|
-
attr(el, "aria-" + dashcase(key), value[key] == null ? null : value[key] + "");
|
|
689
|
-
};
|
|
690
|
-
return (state) => update(evaluate(state));
|
|
691
|
-
};
|
|
692
|
-
secondary[""] = (el, expr) => {
|
|
693
|
-
let evaluate = parseExpr(el, expr, ":");
|
|
694
|
-
if (evaluate)
|
|
695
|
-
return (state) => {
|
|
696
|
-
let value = evaluate(state);
|
|
697
|
-
for (let key in value)
|
|
698
|
-
attr(el, dashcase(key), value[key]);
|
|
721
|
+
var mods = {
|
|
722
|
+
throttle(el, cb, opts, limit) {
|
|
723
|
+
limit = Number(limit) || 108;
|
|
724
|
+
let pause, planned, block = () => {
|
|
725
|
+
pause = true;
|
|
726
|
+
setTimeout(() => {
|
|
727
|
+
pause = false;
|
|
728
|
+
if (planned)
|
|
729
|
+
cb(e), planned = false, block();
|
|
730
|
+
});
|
|
699
731
|
};
|
|
732
|
+
return [el, (e3) => {
|
|
733
|
+
if (pause)
|
|
734
|
+
return planned = true;
|
|
735
|
+
cb(e3);
|
|
736
|
+
block();
|
|
737
|
+
}];
|
|
738
|
+
},
|
|
739
|
+
debounce(el, cb, opts, wait) {
|
|
740
|
+
wait = Number(wait) || 108;
|
|
741
|
+
let timeout, later = () => {
|
|
742
|
+
timeout = null;
|
|
743
|
+
cb(e);
|
|
744
|
+
};
|
|
745
|
+
return [el, (e3) => {
|
|
746
|
+
clearTimeout(timeout);
|
|
747
|
+
timeout = setTimeout(later, wait);
|
|
748
|
+
}];
|
|
749
|
+
},
|
|
750
|
+
window(el, cb) {
|
|
751
|
+
return [window, cb];
|
|
752
|
+
},
|
|
753
|
+
document(el, cb) {
|
|
754
|
+
return [document, cb];
|
|
755
|
+
},
|
|
756
|
+
outside(el, cb) {
|
|
757
|
+
return [el, (e3) => {
|
|
758
|
+
if (el.contains(e3.target))
|
|
759
|
+
return;
|
|
760
|
+
if (e3.target.isConnected === false)
|
|
761
|
+
return;
|
|
762
|
+
if (el.offsetWidth < 1 && el.offsetHeight < 1)
|
|
763
|
+
return;
|
|
764
|
+
cb(e3);
|
|
765
|
+
}];
|
|
766
|
+
},
|
|
767
|
+
prevent(el, cb) {
|
|
768
|
+
return [el, (e3) => {
|
|
769
|
+
e3.preventDefault();
|
|
770
|
+
cb(e3);
|
|
771
|
+
}];
|
|
772
|
+
},
|
|
773
|
+
stop(el, cb) {
|
|
774
|
+
return [el, (e3) => {
|
|
775
|
+
e3.stopPropagation();
|
|
776
|
+
cb(e3);
|
|
777
|
+
}];
|
|
778
|
+
},
|
|
779
|
+
self(el, cb) {
|
|
780
|
+
return [el, (e3) => {
|
|
781
|
+
e3.target === el && cb(e3);
|
|
782
|
+
}];
|
|
783
|
+
},
|
|
784
|
+
once(el, cb, opts) {
|
|
785
|
+
opts.once = true;
|
|
786
|
+
return [el, cb];
|
|
787
|
+
},
|
|
788
|
+
passive(el, cb, opts) {
|
|
789
|
+
opts.passive = true;
|
|
790
|
+
return [el, cb];
|
|
791
|
+
},
|
|
792
|
+
capture(el, cb, opts) {
|
|
793
|
+
opts.capture = true;
|
|
794
|
+
return [el, cb];
|
|
795
|
+
}
|
|
700
796
|
};
|
|
701
|
-
var
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
797
|
+
var keys = {
|
|
798
|
+
ctrl: "Control Ctrl",
|
|
799
|
+
shift: "Shift",
|
|
800
|
+
alt: "Alt",
|
|
801
|
+
meta: "Meta",
|
|
802
|
+
cmd: "Meta",
|
|
803
|
+
down: "ArrowDown",
|
|
804
|
+
up: "ArrowUp",
|
|
805
|
+
left: "ArrowLeft",
|
|
806
|
+
right: "ArrowRight",
|
|
807
|
+
arrowdown: "ArrowDown",
|
|
808
|
+
arrowup: "ArrowUp",
|
|
809
|
+
arrowleft: "ArrowLeft",
|
|
810
|
+
arrowright: "ArrowRight",
|
|
811
|
+
end: "End",
|
|
812
|
+
home: "Home",
|
|
813
|
+
pagedown: "PageDown",
|
|
814
|
+
pageup: "PageUp",
|
|
815
|
+
enter: "Enter",
|
|
816
|
+
plus: "+",
|
|
817
|
+
minus: "-",
|
|
818
|
+
star: "*",
|
|
819
|
+
slash: "/",
|
|
820
|
+
period: ".",
|
|
821
|
+
equal: "=",
|
|
822
|
+
underscore: "_",
|
|
823
|
+
esc: "Escape",
|
|
824
|
+
escape: "Escape",
|
|
825
|
+
tab: "Tab",
|
|
826
|
+
space: " ",
|
|
827
|
+
backspace: "Backspace",
|
|
828
|
+
delete: "Delete"
|
|
829
|
+
};
|
|
830
|
+
for (let keyAttr in keys) {
|
|
831
|
+
let keyName = keys[keyAttr];
|
|
832
|
+
mods[keyAttr] = (el, cb, opts, extraKey) => [el, (e3) => {
|
|
833
|
+
if (!e3.key || !keyName.includes(e3.key))
|
|
834
|
+
return;
|
|
835
|
+
cb(e3);
|
|
836
|
+
}];
|
|
837
|
+
}
|
|
713
838
|
var attr = (el, name, v2) => {
|
|
714
839
|
if (v2 == null || v2 === false)
|
|
715
840
|
el.removeAttribute(name);
|
|
@@ -723,16 +848,16 @@ function parseExpr(el, expression, dir) {
|
|
|
723
848
|
let rightSideSafeExpression = /^[\n\s]*if.*\(.*\)/.test(expression) || /^(let|const)\s/.test(expression) ? `(() => { ${expression} })()` : expression;
|
|
724
849
|
try {
|
|
725
850
|
evaluate = evaluatorMemo[expression] = new Function(`__scope`, `with (__scope) { return ${rightSideSafeExpression} };`);
|
|
726
|
-
} catch (
|
|
727
|
-
return exprError(
|
|
851
|
+
} catch (e3) {
|
|
852
|
+
return exprError(e3, el, expression, dir);
|
|
728
853
|
}
|
|
729
854
|
}
|
|
730
855
|
return (state) => {
|
|
731
856
|
let result;
|
|
732
857
|
try {
|
|
733
858
|
result = evaluate.call(el, state);
|
|
734
|
-
} catch (
|
|
735
|
-
return exprError(
|
|
859
|
+
} catch (e3) {
|
|
860
|
+
return exprError(e3, el, expression, dir);
|
|
736
861
|
}
|
|
737
862
|
return result;
|
|
738
863
|
};
|
package/sprae.min.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
function t(){throw new Error("Cycle detected")}function e(){if(n>1)n--;else{for(var t,e=!1;void 0!==r;){var i=r;for(r=void 0,o++;void 0!==i;){var s=i.o;if(i.o=void 0,i.f&=-3,!(8&i.f)&&u(i))try{i.c()}catch(i){e||(t=i,e=!0)}i=s}}if(o=0,n--,e)throw t}}var i=void 0,r=void 0,n=0,o=0,s=0;function l(t){if(void 0!==i){var e=t.n;if(void 0===e||e.t!==i)return i.s=e={i:0,S:t,p:void 0,n:i.s,t:i,e:void 0,x:void 0,r:e},t.n=e,32&i.f&&t.S(e),e;if(-1===e.i)return e.i=0,void 0!==e.p&&(e.p.n=e.n,void 0!==e.n&&(e.n.p=e.p),e.p=void 0,e.n=i.s,i.s.p=e,i.s=e),e}}function f(t){this.v=t,this.i=0,this.n=void 0,this.t=void 0}function u(t){for(var e=t.s;void 0!==e;e=e.n)if(e.S.i!==e.i||!e.S.h()||e.S.i!==e.i)return!0;return!1}function a(t){for(var e=t.s;void 0!==e;e=e.n){var i=e.S.n;void 0!==i&&(e.r=i),e.S.n=e,e.i=-1}}function h(t){for(var e=t.s,i=void 0;void 0!==e;){var r=e.n;-1===e.i?(e.S.U(e),e.n=void 0):(void 0!==i&&(i.p=e),e.p=void 0,e.n=i,i=e),e.S.n=e.r,void 0!==e.r&&(e.r=void 0),e=r}t.s=i}function c(t){f.call(this,void 0),this.x=t,this.s=void 0,this.g=s-1,this.f=4}function v(t){var r=t.u;if(t.u=void 0,"function"==typeof r){n++;var o=i;i=void 0;try{r()}catch(e){throw t.f&=-2,t.f|=8,p(t),e}finally{i=o,e()}}}function p(t){for(var e=t.s;void 0!==e;e=e.n)e.S.U(e);t.x=void 0,t.s=void 0,v(t)}function d(t){if(i!==this)throw new Error("Out-of-order effect");h(this),i=t,this.f&=-2,8&this.f&&p(this),e()}function y(t){this.x=t,this.u=void 0,this.s=void 0,this.o=void 0,this.f=32}function b(t){var e=new y(t);return e.c(),e.d.bind(e)}f.prototype.h=function(){return!0},f.prototype.S=function(t){this.t!==t&&void 0===t.e&&(t.x=this.t,void 0!==this.t&&(this.t.e=t),this.t=t)},f.prototype.U=function(t){var e=t.e,i=t.x;void 0!==e&&(e.x=i,t.e=void 0),void 0!==i&&(i.e=e,t.x=void 0),t===this.t&&(this.t=i)},f.prototype.subscribe=function(t){var e=this;return b((function(){var i=e.value,r=32&this.f;this.f&=-33;try{t(i)}finally{this.f|=r}}))},f.prototype.valueOf=function(){return this.value},f.prototype.toString=function(){return this.value+""},f.prototype.peek=function(){return this.v},Object.defineProperty(f.prototype,"value",{get:function(){var t=l(this);return void 0!==t&&(t.i=this.i),this.v},set:function(i){if(i!==this.v){o>100&&t(),this.v=i,this.i++,s++,n++;try{for(var r=this.t;void 0!==r;r=r.x)r.t.N()}finally{e()}}}}),(c.prototype=new f).h=function(){if(this.f&=-3,1&this.f)return!1;if(32==(36&this.f))return!0;if(this.f&=-5,this.g===s)return!0;if(this.g=s,this.f|=1,this.i>0&&!u(this))return this.f&=-2,!0;var t=i;try{a(this),i=this;var e=this.x();(16&this.f||this.v!==e||0===this.i)&&(this.v=e,this.f&=-17,this.i++)}catch(t){this.v=t,this.f|=16,this.i++}return i=t,h(this),this.f&=-2,!0},c.prototype.S=function(t){if(void 0===this.t){this.f|=36;for(var e=this.s;void 0!==e;e=e.n)e.S.S(e)}f.prototype.S.call(this,t)},c.prototype.U=function(t){if(f.prototype.U.call(this,t),void 0===this.t){this.f&=-33;for(var e=this.s;void 0!==e;e=e.n)e.S.U(e)}},c.prototype.N=function(){if(!(2&this.f)){this.f|=6;for(var t=this.t;void 0!==t;t=t.x)t.t.N()}},c.prototype.peek=function(){if(this.h()||t(),16&this.f)throw this.v;return this.v},Object.defineProperty(c.prototype,"value",{get:function(){1&this.f&&t();var e=l(this);if(this.h(),void 0!==e&&(e.i=this.i),16&this.f)throw this.v;return this.v}}),y.prototype.c=function(){var t=this.S();try{8&this.f||void 0===this.x||(this.u=this.x())}finally{t()}},y.prototype.S=function(){1&this.f&&t(),this.f|=1,this.f&=-9,v(this),a(this),n++;var e=i;return i=this,d.bind(this,e)},y.prototype.N=function(){2&this.f||(this.f|=2,this.o=r,r=this)},y.prototype.d=function(){this.f|=8,1&this.f||p(this)},Symbol.observable||=Symbol("observable");var m=new FinalizationRegistry((t=>t.call?.())),g=(t,e,i,r,n,o)=>{return t&&(s=(t[Symbol.observable]?.()||t).subscribe?.(e,i,r),o=s&&(()=>s.unsubscribe?.())||t.set&&t.call?.(n,e)||(t.then?.((t=>(!n&&e(t),r?.())),i)||(async o=>{try{for await(o of t){if(n)return;e(o)}r?.()}catch(t){i?.(t)}})())&&(t=>n=1),m.register(t,o),o);var s},S=t=>t&&t[A],A=Symbol("signal-struct");function w(t,e){if(S(t)&&!e)return t;if(x(t)){const n=Object.create(e||Object.getPrototypeOf(t)),o={},s=Object.getOwnPropertyDescriptors(t);for(let t in s){let e=s[t];if(e.get){let i=o[t]=new c(e.get.bind(n));Object.defineProperty(n,t,{get:()=>i.value,set:e.set?.bind(n),configurable:!1,enumerable:!0})}else{let s=e.value,l=(r=s)&&!!(r[Symbol.observable]||r[Symbol.asyncIterator]||r.call&&r.set||r.subscribe||r.then),u=o[t]=(i=s)&&i.peek?s:new f(l?void 0:x(s)?Object.seal(w(s)):Array.isArray(s)?w(s):s);l&&g(s,(t=>u.value=t)),Object.defineProperty(n,t,{get:()=>u.value,set(t){if(x(t)){if(x(u.value))try{return void Object.assign(u.value,t)}catch(t){}u.value=Object.seal(w(t))}else Array.isArray(t)?u.value=w(t):u.value=t},enumerable:!0,configurable:!1})}}return Object.defineProperty(n,A,{configurable:!1,enumerable:!1,value:!0}),n}var i,r;return Array.isArray(t)&&!S(t[0])?t.map((t=>w(t))):t}function x(t){return t&&t.constructor===Object}w.isStruct=S;var O=(t,e,i,r=null)=>{let n,o,s,l=0,f=i.length,u=e.length,{remove:a,same:h,insert:c,replace:v}=O;for(;l<f&&l<u&&h(e[l],i[l]);)l++;for(;l<f&&l<u&&h(i[f-1],e[u-1]);)r=i[(--u,--f)];if(l==u)for(;l<f;)c(r,i[l++],t);else{for(n=e[l];l<f;)s=i[l++],o=n?n.nextSibling:r,h(n,s)?n=o:l<f&&h(i[l],o)?(v(n,s,t),n=o):c(n,s,t);for(;!h(n,r);)o=n.nextSibling,a(n,t),n=o}return i};O.same=(t,e)=>t==e,O.replace=(t,e,i)=>i.replaceChild(e,t),O.insert=(t,e,i)=>i.insertBefore(e,t),O.remove=(t,e)=>e.removeChild(t);var j=O,N={},E={},k={},W=t=>null===t?E:void 0===t?k:"number"==typeof t||t instanceof Number?N[t]||(N[t]=new Number(t)):"string"==typeof t||t instanceof String?N[t]||(N[t]=new String(t)):"boolean"==typeof t||t instanceof Boolean?N[t]||(N[t]=new Boolean(t)):t,$={},P={};$.if=(t,e)=>{let i=document.createTextNode(""),r=[M(t,e,":if")],n=[t],o=t;for(;(o=t.nextElementSibling)&&o.hasAttribute(":else");)o.removeAttribute(":else"),(e=o.getAttribute(":if"))?(o.removeAttribute(":if"),o.remove(),n.push(o),r.push(M(t,e,":else :if"))):(o.remove(),n.push(o),r.push((()=>1)));return t.replaceWith(o=i),t=>{let e=r.findIndex((e=>e(t)));n[e]!=o&&((o[C]||o).replaceWith(o=n[e]||i),z(o,t))}},$.with=(t,e,i)=>{z(t,w(M(t,e,"with")(i),i))};var C=Symbol(":each");$.each=(t,e)=>{let i=function(t){let e=/,([^,\}\]]*)(?:,([^,\}\]]*))?$/,i=t.match(/([\s\S]*?)\s+(?:in|of)\s+([\s\S]*)/);if(!i)return;let r=i[2].trim(),n=i[1].replace(/^\s*\(|\)\s*$/g,"").trim(),o=n.match(e);return o?[n.replace(e,"").trim(),o[1].trim(),r]:[n,"",r]}(e);if(!i)return R(new Error,t,e);const r=t[C]=document.createTextNode("");t.replaceWith(r);const n=M(t,i[2],":each"),o=t.getAttribute(":key"),s=o?M(null,o):null;t.removeAttribute(":key");const l=new WeakMap,f=new WeakMap;let u=[];return o=>{let a=n(o);a?"number"==typeof a?a=Array.from({length:a},((t,e)=>[e,e+1])):Array.isArray(a)?a=a.map(((t,e)=>[e+1,t])):"object"==typeof a?a=Object.entries(a):R(Error("Bad list value"),t,e,":each"):a=[];let h=[],c=[];for(let[e,r]of a){let n,u,a=s?.({[i[0]]:r,[i[1]]:e});("string"==typeof(v=a)||"boolean"==typeof v||"number"==typeof v)&&(a=W(a)),null==a?n=t.cloneNode(!0):(n=f.get(a))||f.set(a,n=t.cloneNode(!0)),h.push(n),null!=a&&(u=l.get(a))?u[i[0]]=r:(u=w({[i[0]]:r,[i[1]]:e},o),null!=a&&l.set(a,u)),c.push(u)}var v;j(r.parentNode,u,h,r),u=h;for(let t=0;t<h.length;t++)z(h[t],c[t])}},P.ref=(t,e,i)=>{i[e]=t},P.id=(t,e)=>{let i=M(t,e,":id");return e=>{return r=i(e),t.id=r||0===r?r:"";var r}},P.class=(t,e)=>{let i=M(t,e,":class"),r=t.className;return e=>{let n=i(e);t.className=r+typeof n=="string"?n:(Array.isArray(n)?n:Object.entries(n).map((([t,e])=>e?t:""))).filter(Boolean).join(" ")}},P.style=(t,e)=>{let i=M(t,e,":style"),r=t.getAttribute("style")||"";return r.endsWith(";")||(r+="; "),e=>{let n=i(e);if("string"==typeof n)t.setAttribute("style",r+n);else for(let e in n)t.style[e]=n[e]}},P.text=(t,e)=>{let i=M(t,e,":text");return e=>{let r=i(e);t.textContent=null==r?"":r}},P.value=(t,e)=>{let i,r,n=M(t,e,":value"),o="text"===t.type||""===t.type?e=>t.setAttribute("value",t.value=null==e?"":e):"TEXTAREA"===t.tagName||"text"===t.type||""===t.type?e=>(i=t.selectionStart,r=t.selectionEnd,t.setAttribute("value",t.value=null==e?"":e),i&&t.setSelectionRange(i,r)):"checkbox"===t.type?e=>(t.value=e?"on":"",D(t,"checked",e)):"select-one"===t.type?e=>{for(let e in t.options)e.removeAttribute("selected");t.value=e,t.selectedOptions[0]?.setAttribute("selected","")}:e=>t.value=e;return t=>o(n(t))},P.on=(t,e)=>{let i=M(t,e,":on");return e=>{let r=i(e);for(let e in r)B(t,e,r[e]);return()=>{for(let e in r)L(t,e,r[e])}}};var U=Symbol("stop"),B=(t,e,i)=>{if(e.indexOf("..")<0)t.addEventListener(e,i);else{const r=e.split("..").map((t=>t.startsWith("on")?t.slice(2):t)),n=(e,o=0)=>{let s=l=>{t.removeEventListener(r[o],s),"function"!=typeof(e=e.call(t,l))&&(e=()=>{}),++o<r.length?n(e,o):i[U]||n(i)};t.addEventListener(r[o],s)};n(i)}},L=(t,e,i)=>{e.indexOf("..")>=0&&(i[U]=!0),t.removeEventListener(e,i)};P.data=(t,e)=>{let i=M(t,e,":data");return e=>{let r=i(e);for(let e in r)t.dataset[e]=r[e]}},P.aria=(t,e)=>{let i=M(t,e,":aria");return e=>(e=>{for(let i in e)D(t,"aria-"+F(i),null==e[i]?null:e[i]+"")})(i(e))},P[""]=(t,e)=>{let i=M(t,e,":");if(i)return e=>{let r=i(e);for(let e in r)D(t,F(e),r[e])}};var T=(t,e,i,r)=>{let n=r.startsWith("on")&&r.slice(2),o=M(t,e,":"+r);if(o)return n?e=>{let i=o(e);if(i)return B(t,n,i),()=>L(t,n,i)}:e=>D(t,r,o(e))},D=(t,e,i)=>{null==i||!1===i?t.removeAttribute(e):t.setAttribute(e,!0===i?"":"number"==typeof i||"string"==typeof i?i:"")},_={};function M(t,e,i){let r=_[e];if(!r){let n=/^[\n\s]*if.*\(.*\)/.test(e)||/^(let|const)\s/.test(e)?`(() => { ${e} })()`:e;try{r=_[e]=new Function("__scope",`with (__scope) { return ${n} };`)}catch(r){return R(r,t,e,i)}}return n=>{let o;try{o=r.call(t,n)}catch(r){return R(r,t,e,i)}return o}}function R(t,e,i,r){Object.assign(t,{element:e,expression:i}),console.warn(`∴ ${t.message}\n\n${r}=${i?`"${i}"\n\n`:""}`,e),setTimeout((()=>{throw t}),0)}function F(t){return t.replace(/[A-Z\u00C0-\u00D6\u00D8-\u00DE]/g,(t=>"-"+t.toLowerCase()))}var I=new WeakMap;function z(t,i){if(!t.children)return;if(I.has(t)){let r=I.get(t);return function(t){if(n>0)return t();n++;try{t()}finally{e()}}((()=>Object.assign(r,i))),r}const r=w(i||{}),o=[],s=(t,e=t.parentNode)=>{for(let i in $){let n=":"+i;if(t.hasAttribute?.(n)){let s=t.getAttribute(n);if(t.removeAttribute(n),!s)continue;if(o.push($[i](t,s,r,i)),I.has(t)||t.parentNode!==e)return!1}}if(t.attributes)for(let i=0;i<t.attributes.length;){let n=t.attributes[i];if(":"!==n.name[0]){i++;continue}t.removeAttribute(n.name);let s=n.value;if(!s)continue;let l=n.name.slice(1).split(":");for(let i of l){let n=P[i]||T;if(o.push(n(t,s,r,i)),I.has(t)||t.parentNode!==e)return!1}}for(let e,i=0;e=t.children[i];i++)!1===s(e,t)&&i--};s(t);for(let t of o)if(t){let e;b((()=>{"function"==typeof e&&e(),e=t(r)}))}return Object.seal(r),I.set(t,r),r}var X=z;export{X as default};
|
|
1
|
+
function t(){throw new Error("Cycle detected")}function r(){if(o>1)o--;else{for(var t,e=!1;void 0!==n;){var r=n;for(n=void 0,s++;void 0!==r;){var i=r.o;if(r.o=void 0,r.f&=-3,!(8&r.f)&&f(r))try{r.c()}catch(r){e||(t=r,e=!0)}r=i}}if(s=0,o--,e)throw t}}var i=void 0,n=void 0,o=0,s=0,l=0;function a(t){if(void 0!==i){var e=t.n;if(void 0===e||e.t!==i)return i.s=e={i:0,S:t,p:void 0,n:i.s,t:i,e:void 0,x:void 0,r:e},t.n=e,32&i.f&&t.S(e),e;if(-1===e.i)return e.i=0,void 0!==e.p&&(e.p.n=e.n,void 0!==e.n&&(e.n.p=e.p),e.p=void 0,e.n=i.s,i.s.p=e,i.s=e),e}}function u(t){this.v=t,this.i=0,this.n=void 0,this.t=void 0}function f(t){for(var e=t.s;void 0!==e;e=e.n)if(e.S.i!==e.i||!e.S.h()||e.S.i!==e.i)return!0;return!1}function c(t){for(var e=t.s;void 0!==e;e=e.n){var r=e.S.n;void 0!==r&&(e.r=r),e.S.n=e,e.i=-1}}function h(t){for(var e=t.s,r=void 0;void 0!==e;){var i=e.n;-1===e.i?(e.S.U(e),e.n=void 0):(void 0!==r&&(r.p=e),e.p=void 0,e.n=r,r=e),e.S.n=e.r,void 0!==e.r&&(e.r=void 0),e=i}t.s=r}function v(t){u.call(this,void 0),this.x=t,this.s=void 0,this.g=l-1,this.f=4}function p(t){var e=t.u;if(t.u=void 0,"function"==typeof e){o++;var n=i;i=void 0;try{e()}catch(e){throw t.f&=-2,t.f|=8,d(t),e}finally{i=n,r()}}}function d(t){for(var e=t.s;void 0!==e;e=e.n)e.S.U(e);t.x=void 0,t.s=void 0,p(t)}function y(t){if(i!==this)throw new Error("Out-of-order effect");h(this),i=t,this.f&=-2,8&this.f&&d(this),r()}function b(t){this.x=t,this.u=void 0,this.s=void 0,this.o=void 0,this.f=32}function m(t){var e=new b(t);return e.c(),e.d.bind(e)}u.prototype.h=function(){return!0},u.prototype.S=function(t){this.t!==t&&void 0===t.e&&(t.x=this.t,void 0!==this.t&&(this.t.e=t),this.t=t)},u.prototype.U=function(t){var e=t.e,r=t.x;void 0!==e&&(e.x=r,t.e=void 0),void 0!==r&&(r.e=e,t.x=void 0),t===this.t&&(this.t=r)},u.prototype.subscribe=function(t){var e=this;return m((function(){var r=e.value,i=32&this.f;this.f&=-33;try{t(r)}finally{this.f|=i}}))},u.prototype.valueOf=function(){return this.value},u.prototype.toString=function(){return this.value+""},u.prototype.peek=function(){return this.v},Object.defineProperty(u.prototype,"value",{get:function(){var t=a(this);return void 0!==t&&(t.i=this.i),this.v},set:function(e){if(e!==this.v){s>100&&t(),this.v=e,this.i++,l++,o++;try{for(var i=this.t;void 0!==i;i=i.x)i.t.N()}finally{r()}}}}),(v.prototype=new u).h=function(){if(this.f&=-3,1&this.f)return!1;if(32==(36&this.f))return!0;if(this.f&=-5,this.g===l)return!0;if(this.g=l,this.f|=1,this.i>0&&!f(this))return this.f&=-2,!0;var t=i;try{c(this),i=this;var e=this.x();(16&this.f||this.v!==e||0===this.i)&&(this.v=e,this.f&=-17,this.i++)}catch(t){this.v=t,this.f|=16,this.i++}return i=t,h(this),this.f&=-2,!0},v.prototype.S=function(t){if(void 0===this.t){this.f|=36;for(var e=this.s;void 0!==e;e=e.n)e.S.S(e)}u.prototype.S.call(this,t)},v.prototype.U=function(t){if(u.prototype.U.call(this,t),void 0===this.t){this.f&=-33;for(var e=this.s;void 0!==e;e=e.n)e.S.U(e)}},v.prototype.N=function(){if(!(2&this.f)){this.f|=6;for(var t=this.t;void 0!==t;t=t.x)t.t.N()}},v.prototype.peek=function(){if(this.h()||t(),16&this.f)throw this.v;return this.v},Object.defineProperty(v.prototype,"value",{get:function(){1&this.f&&t();var e=a(this);if(this.h(),void 0!==e&&(e.i=this.i),16&this.f)throw this.v;return this.v}}),b.prototype.c=function(){var t=this.S();try{8&this.f||void 0===this.x||(this.u=this.x())}finally{t()}},b.prototype.S=function(){1&this.f&&t(),this.f|=1,this.f&=-9,p(this),c(this),o++;var e=i;return i=this,y.bind(this,e)},b.prototype.N=function(){2&this.f||(this.f|=2,this.o=n,n=this)},b.prototype.d=function(){this.f|=8,1&this.f||d(this)},Symbol.observable||=Symbol("observable");var g=new FinalizationRegistry((t=>t.call?.())),w=(t,e,r,i,n,o)=>{return t&&(s=(t[Symbol.observable]?.()||t).subscribe?.(e,r,i),o=s&&(()=>s.unsubscribe?.())||t.set&&t.call?.(n,e)||(t.then?.((t=>(!n&&e(t),i?.())),r)||(async o=>{try{for await(o of t){if(n)return;e(o)}i?.()}catch(t){r?.(t)}})())&&(t=>n=1),g.register(t,o),o);var s},A=t=>t&&t[S],S=Symbol("signal-struct");function x(t,e){if(A(t)&&!e)return t;if(O(t)){const n=Object.create(e||Object.getPrototypeOf(t)),o={},s=Object.getOwnPropertyDescriptors(t);for(let t in s){let e=s[t];if(e.get){let r=o[t]=new v(e.get.bind(n));Object.defineProperty(n,t,{get:()=>r.value,set:e.set?.bind(n),configurable:!1,enumerable:!0})}else{let s=e.value,l=(i=s)&&!!(i[Symbol.observable]||i[Symbol.asyncIterator]||i.call&&i.set||i.subscribe||i.then),a=o[t]=(r=s)&&r.peek?s:new u(l?void 0:O(s)?Object.seal(x(s)):Array.isArray(s)?x(s):s);l&&w(s,(t=>a.value=t)),Object.defineProperty(n,t,{get:()=>a.value,set(t){if(O(t)){if(O(a.value))try{return void Object.assign(a.value,t)}catch(t){}a.value=Object.seal(x(t))}else Array.isArray(t)?a.value=x(t):a.value=t},enumerable:!0,configurable:!1})}}return Object.defineProperty(n,S,{configurable:!1,enumerable:!1,value:!0}),n}var r,i;if(Array.isArray(t)&&!A(t[0]))for(let e=0;e<t.length;e++)t[e]=x(t[e]);return t}function O(t){return t&&t.constructor===Object}x.isStruct=A;var j=(t,e,r,i=null)=>{let n,o,s,l=0,a=r.length,u=e.length,{remove:f,same:c,insert:h,replace:v}=j;for(;l<a&&l<u&&c(e[l],r[l]);)l++;for(;l<a&&l<u&&c(r[a-1],e[u-1]);)i=r[(--u,--a)];if(l==u)for(;l<a;)h(i,r[l++],t);else{for(n=e[l];l<a;)s=r[l++],o=n?n.nextSibling:i,c(n,s)?n=o:l<a&&c(r[l],o)?(v(n,s,t),n=o):h(n,s,t);for(;!c(n,i);)o=n.nextSibling,f(n,t),n=o}return r};j.same=(t,e)=>t==e,j.replace=(t,e,r)=>r.replaceChild(e,t),j.insert=(t,e,r)=>r.insertBefore(e,t),j.remove=(t,e)=>e.removeChild(t);var N=j,E={},k={},P={},W=t=>null===t?k:void 0===t?P:"number"==typeof t||t instanceof Number?E[t]||(E[t]=new Number(t)):"string"==typeof t||t instanceof String?E[t]||(E[t]=new String(t)):"boolean"==typeof t||t instanceof Boolean?E[t]||(E[t]=new Boolean(t)):t,C={},D={};C.if=(t,e)=>{let r=document.createTextNode(""),i=[H(t,e,":if")],n=[t],o=t;for(;(o=t.nextElementSibling)&&o.hasAttribute(":else");)o.removeAttribute(":else"),(e=o.getAttribute(":if"))?(o.removeAttribute(":if"),o.remove(),n.push(o),i.push(H(t,e,":else :if"))):(o.remove(),n.push(o),i.push((()=>1)));return t.replaceWith(o=r),t=>{let e=i.findIndex((e=>e(t)));n[e]!=o&&((o[T]||o).replaceWith(o=n[e]||r),X(o,t))}},C.with=(t,e,r)=>{X(t,x(H(t,e,"with")(r),r))};var T=Symbol(":each");C.each=(t,e)=>{let r=function(t){let e=/,([^,\}\]]*)(?:,([^,\}\]]*))?$/,r=t.match(/([\s\S]*?)\s+(?:in|of)\s+([\s\S]*)/);if(!r)return;let i=r[2].trim(),n=r[1].replace(/^\s*\(|\)\s*$/g,"").trim(),o=n.match(e);return o?[n.replace(e,"").trim(),o[1].trim(),i]:[n,"",i]}(e);if(!r)return I(new Error,t,e);const i=t[T]=document.createTextNode("");t.replaceWith(i);const n=H(t,r[2],":each"),o=t.getAttribute(":key"),s=o?H(null,o):null;t.removeAttribute(":key");const l=new WeakMap,a=new WeakMap;let u=[];return o=>{let f=n(o);f?"number"==typeof f?f=Array.from({length:f},((t,e)=>[e,e+1])):Array.isArray(f)?f=f.map(((t,e)=>[e+1,t])):"object"==typeof f?f=Object.entries(f):I(Error("Bad list value"),t,e,":each"):f=[];let c=[],h=[];for(let[e,i]of f){let n,u,f=s?.({[r[0]]:i,[r[1]]:e});("string"==typeof(v=f)||"boolean"==typeof v||"number"==typeof v)&&(f=W(f)),null==f?n=t.cloneNode(!0):(n=a.get(f))||a.set(f,n=t.cloneNode(!0)),c.push(n),null!=f&&(u=l.get(f))?u[r[0]]=i:(u=x({[r[0]]:i,[r[1]]:e},o),null!=f&&l.set(f,u)),h.push(u)}var v;N(i.parentNode,u,c,i),u=c;for(let t=0;t<c.length;t++)X(c[t],h[t])}},D.ref=(t,e,r)=>{r[e]=t},D.id=(t,e)=>{let r=H(t,e,":id");return e=>{return i=r(e),t.id=i||0===i?i:"";var i}},D.class=(t,e)=>{let r=H(t,e,":class"),i=t.className;return e=>{let n=r(e);t.className=i+typeof n=="string"?n:(Array.isArray(n)?n:Object.entries(n).map((([t,e])=>e?t:""))).filter(Boolean).join(" ")}},D.style=(t,e)=>{let r=H(t,e,":style"),i=t.getAttribute("style")||"";return i.endsWith(";")||(i+="; "),e=>{let n=r(e);if("string"==typeof n)t.setAttribute("style",i+n);else for(let e in n)t.style[e]=n[e]}},D.text=(t,e)=>{let r=H(t,e,":text");return e=>{let i=r(e);t.textContent=null==i?"":i}},D.data=(t,e)=>{let r=H(t,e,":data");return e=>{let i=r(e);for(let e in i)t.dataset[e]=i[e]}},D.aria=(t,e)=>{let r=H(t,e,":aria");return e=>(e=>{for(let r in e)_(t,"aria-"+q(r),null==e[r]?null:e[r]+"")})(r(e))},D[""]=(t,e)=>{let r=H(t,e,":");if(r)return e=>{let i=r(e);for(let e in i)_(t,q(e),i[e])}},D.value=(t,e)=>{let r,i,n=H(t,e,":value"),o="text"===t.type||""===t.type?e=>t.setAttribute("value",t.value=null==e?"":e):"TEXTAREA"===t.tagName||"text"===t.type||""===t.type?e=>(r=t.selectionStart,i=t.selectionEnd,t.setAttribute("value",t.value=null==e?"":e),r&&t.setSelectionRange(r,i)):"checkbox"===t.type?e=>(t.value=e?"on":"",_(t,"checked",e)):"select-one"===t.type?e=>{for(let e in t.options)e.removeAttribute("selected");t.value=e,t.selectedOptions[0]?.setAttribute("selected","")}:e=>t.value=e;return t=>o(n(t))},D.on=(t,e)=>{let r=H(t,e,":on");return e=>{let i=r(e);for(let e in i)L(t,e,i[e]);return()=>{for(let e in i)B(t,e,i[e])}}};var U=(t,e,r,i)=>{let n=i.startsWith("on")&&i.slice(2),o=H(t,e,":"+i);if(o)return n?e=>{let r=o(e);if(r)return L(t,n,r),()=>B(t,n,r)}:e=>_(t,i,o(e))},$=Symbol("stop"),L=(t,e,r)=>{let i=e.split("..").map((t=>t.startsWith("on")?t.slice(2):t)),n={};if(i[0]=i[0].replace(/\.(\w+)?-?([\w]+)?/g,((e,i,o)=>(i=M[i])?([t,r]=i(t,r,n,o),""):"")),1==i.length)t.addEventListener(i[0],r,n);else{const e=(o,s=0)=>{let l=n=>{t.removeEventListener(i[s],l),"function"!=typeof(o=o.call(t,n))&&(o=()=>{}),++s<i.length?e(o,s):r[$]||e(r)};t.addEventListener(i[s],l,n)};e(r)}},B=(t,e,r)=>{e.indexOf("..")>=0&&(r[$]=!0),t.removeEventListener(e,r)},M={throttle(t,r,i,n){n=Number(n)||108;let o,s,l=()=>{o=!0,setTimeout((()=>{o=!1,s&&(r(e),s=!1,l())}))};return[t,t=>{if(o)return s=!0;r(t),l()}]},debounce(t,r,i,n){n=Number(n)||108;let o,s=()=>{o=null,r(e)};return[t,t=>{clearTimeout(o),o=setTimeout(s,n)}]},window:(t,e)=>[window,e],document:(t,e)=>[document,e],outside:(t,e)=>[t,r=>{t.contains(r.target)||!1!==r.target.isConnected&&(t.offsetWidth<1&&t.offsetHeight<1||e(r))}],prevent:(t,e)=>[t,t=>{t.preventDefault(),e(t)}],stop:(t,e)=>[t,t=>{t.stopPropagation(),e(t)}],self:(t,e)=>[t,r=>{r.target===t&&e(r)}],once:(t,e,r)=>(r.once=!0,[t,e]),passive:(t,e,r)=>(r.passive=!0,[t,e]),capture:(t,e,r)=>(r.capture=!0,[t,e])},R={ctrl:"Control Ctrl",shift:"Shift",alt:"Alt",meta:"Meta",cmd:"Meta",down:"ArrowDown",up:"ArrowUp",left:"ArrowLeft",right:"ArrowRight",arrowdown:"ArrowDown",arrowup:"ArrowUp",arrowleft:"ArrowLeft",arrowright:"ArrowRight",end:"End",home:"Home",pagedown:"PageDown",pageup:"PageUp",enter:"Enter",plus:"+",minus:"-",star:"*",slash:"/",period:".",equal:"=",underscore:"_",esc:"Escape",escape:"Escape",tab:"Tab",space:" ",backspace:"Backspace",delete:"Delete"};for(let t in R){let e=R[t];M[t]=(t,r,i,n)=>[t,t=>{t.key&&e.includes(t.key)&&r(t)}]}var _=(t,e,r)=>{null==r||!1===r?t.removeAttribute(e):t.setAttribute(e,!0===r?"":"number"==typeof r||"string"==typeof r?r:"")},F={};function H(t,e,r){let i=F[e];if(!i){let n=/^[\n\s]*if.*\(.*\)/.test(e)||/^(let|const)\s/.test(e)?`(() => { ${e} })()`:e;try{i=F[e]=new Function("__scope",`with (__scope) { return ${n} };`)}catch(i){return I(i,t,e,r)}}return n=>{let o;try{o=i.call(t,n)}catch(i){return I(i,t,e,r)}return o}}function I(t,e,r,i){Object.assign(t,{element:e,expression:r}),console.warn(`∴ ${t.message}\n\n${i}=${r?`"${r}"\n\n`:""}`,e),setTimeout((()=>{throw t}),0)}function q(t){return t.replace(/[A-Z\u00C0-\u00D6\u00D8-\u00DE]/g,(t=>"-"+t.toLowerCase()))}var z=new WeakMap;function X(t,e){if(!t.children)return;if(z.has(t)){let i=z.get(t);return function(t){if(o>0)return t();o++;try{t()}finally{r()}}((()=>Object.assign(i,e))),i}const i=x(e||{}),n=[],s=(t,e=t.parentNode)=>{for(let r in C){let o=":"+r;if(t.hasAttribute?.(o)){let s=t.getAttribute(o);if(t.removeAttribute(o),!s)continue;if(n.push(C[r](t,s,i,r)),z.has(t)||t.parentNode!==e)return!1}}if(t.attributes)for(let r=0;r<t.attributes.length;){let o=t.attributes[r];if(":"!==o.name[0]){r++;continue}t.removeAttribute(o.name);let s=o.value;if(!s)continue;let l=o.name.slice(1).split(":");for(let r of l){let o=D[r]||U;if(n.push(o(t,s,i,r)),z.has(t)||t.parentNode!==e)return!1}}for(let e,r=0;e=t.children[r];r++)!1===s(e,t)&&r--};s(t);for(let t of n)if(t){let e;m((()=>{"function"==typeof e&&e(),e=t(i)}))}return Object.seal(i),z.set(t,i),i}var Z=X;export{Z as default};
|
package/src/directives.js
CHANGED
|
@@ -182,6 +182,32 @@ secondary['text'] = (el, expr) => {
|
|
|
182
182
|
}
|
|
183
183
|
}
|
|
184
184
|
|
|
185
|
+
secondary['data'] = (el, expr) => {
|
|
186
|
+
let evaluate = parseExpr(el, expr, ':data')
|
|
187
|
+
|
|
188
|
+
return ((state) => {
|
|
189
|
+
let value = evaluate(state)
|
|
190
|
+
for (let key in value) el.dataset[key] = value[key];
|
|
191
|
+
})
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
secondary['aria'] = (el, expr) => {
|
|
195
|
+
let evaluate = parseExpr(el, expr, ':aria')
|
|
196
|
+
const update = (value) => {
|
|
197
|
+
for (let key in value) attr(el, 'aria-' + dashcase(key), value[key] == null ? null : value[key] + '');
|
|
198
|
+
}
|
|
199
|
+
return ((state) => update(evaluate(state)))
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
// set props in-bulk or run effect
|
|
203
|
+
secondary[''] = (el, expr) => {
|
|
204
|
+
let evaluate = parseExpr(el, expr, ':')
|
|
205
|
+
if (evaluate) return (state) => {
|
|
206
|
+
let value = evaluate(state)
|
|
207
|
+
for (let key in value) attr(el, dashcase(key), value[key]);
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
|
|
185
211
|
// connect expr to element value
|
|
186
212
|
secondary['value'] = (el, expr) => {
|
|
187
213
|
let evaluate = parseExpr(el, expr, ':value')
|
|
@@ -219,13 +245,38 @@ secondary['on'] = (el, expr) => {
|
|
|
219
245
|
}
|
|
220
246
|
}
|
|
221
247
|
|
|
248
|
+
// any unknown directive
|
|
249
|
+
export default (el, expr, state, name) => {
|
|
250
|
+
let evt = name.startsWith('on') && name.slice(2)
|
|
251
|
+
let evaluate = parseExpr(el, expr, ':'+name)
|
|
252
|
+
|
|
253
|
+
if (!evaluate) return
|
|
254
|
+
|
|
255
|
+
if (evt) return state => {
|
|
256
|
+
let value = evaluate(state)
|
|
257
|
+
if (value) {
|
|
258
|
+
addListener(el, evt, value)
|
|
259
|
+
return () => removeListener(el, evt, value)
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
return state => attr(el, name, evaluate(state))
|
|
264
|
+
}
|
|
265
|
+
|
|
222
266
|
const _stop = Symbol('stop')
|
|
223
267
|
const addListener = (el, evt, startFn) => {
|
|
224
|
-
|
|
268
|
+
// ona..onb
|
|
269
|
+
let evts = evt.split('..').map(e => e.startsWith('on') ? e.slice(2) : e),
|
|
270
|
+
opts = {}
|
|
271
|
+
|
|
272
|
+
// onevt.debounce-108
|
|
273
|
+
evts[0] = evts[0].replace(
|
|
274
|
+
/\.(\w+)?-?([\w]+)?/g,
|
|
275
|
+
(match, mod, param) => (mod=mods[mod]) ? ([el, startFn] = mod(el, startFn, opts, param), '') : ''
|
|
276
|
+
);
|
|
225
277
|
|
|
226
|
-
|
|
278
|
+
if (evts.length == 1) el.addEventListener(evts[0], startFn, opts);
|
|
227
279
|
else {
|
|
228
|
-
const evts = evt.split('..').map(e => e.startsWith('on') ? e.slice(2) : e)
|
|
229
280
|
const nextEvt = (fn, cur=0) => {
|
|
230
281
|
let curListener = e => {
|
|
231
282
|
el.removeEventListener(evts[cur], curListener)
|
|
@@ -233,7 +284,7 @@ const addListener = (el, evt, startFn) => {
|
|
|
233
284
|
if (++cur < evts.length) nextEvt(fn, cur);
|
|
234
285
|
else if (!startFn[_stop]) nextEvt(startFn); // update only if chain isn't stopped
|
|
235
286
|
}
|
|
236
|
-
el.addEventListener(evts[cur],curListener)
|
|
287
|
+
el.addEventListener(evts[cur], curListener, opts)
|
|
237
288
|
}
|
|
238
289
|
nextEvt(startFn)
|
|
239
290
|
}
|
|
@@ -243,44 +294,67 @@ const removeListener = (el, evt, fn) => {
|
|
|
243
294
|
el.removeEventListener(evt, fn);
|
|
244
295
|
}
|
|
245
296
|
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
let
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
const update = (value) => {
|
|
258
|
-
for (let key in value) attr(el, 'aria-' + dashcase(key), value[key] == null ? null : value[key] + '');
|
|
259
|
-
}
|
|
260
|
-
return ((state) => update(evaluate(state)))
|
|
261
|
-
}
|
|
262
|
-
|
|
263
|
-
// set props in-bulk or run effect
|
|
264
|
-
secondary[''] = (el, expr) => {
|
|
265
|
-
let evaluate = parseExpr(el, expr, ':')
|
|
266
|
-
if (evaluate) return (state) => {
|
|
267
|
-
let value = evaluate(state)
|
|
268
|
-
for (let key in value) attr(el, dashcase(key), value[key]);
|
|
269
|
-
}
|
|
270
|
-
}
|
|
271
|
-
|
|
272
|
-
// any other prop directive
|
|
273
|
-
export default (el, expr, values, name) => {
|
|
274
|
-
let evt = name.startsWith('on') && name.slice(2)
|
|
275
|
-
let evaluate = parseExpr(el, expr, ':'+name)
|
|
276
|
-
if (evaluate) return evt ? state => {
|
|
277
|
-
let value = evaluate(state)
|
|
278
|
-
if (value) {
|
|
279
|
-
addListener(el, evt, value)
|
|
280
|
-
return () => removeListener(el, evt, value)
|
|
297
|
+
// event modifiers
|
|
298
|
+
const mods = {
|
|
299
|
+
throttle(el, cb, opts, limit) {
|
|
300
|
+
limit = Number(limit) || 108
|
|
301
|
+
let pause, planned, block = () => {
|
|
302
|
+
pause = true
|
|
303
|
+
setTimeout(() => {
|
|
304
|
+
pause = false
|
|
305
|
+
// if event happened during blocked time, it schedules call by the end
|
|
306
|
+
if (planned) cb(e), planned = false, block();
|
|
307
|
+
})
|
|
281
308
|
}
|
|
282
|
-
|
|
283
|
-
|
|
309
|
+
return [el, e => {
|
|
310
|
+
if (pause) return planned = true
|
|
311
|
+
cb(e); block();
|
|
312
|
+
}]
|
|
313
|
+
},
|
|
314
|
+
|
|
315
|
+
debounce(el, cb, opts, wait) {
|
|
316
|
+
wait = Number(wait) || 108;
|
|
317
|
+
let timeout, later = () => { timeout = null; cb(e) }
|
|
318
|
+
return [el, (e) => {
|
|
319
|
+
clearTimeout(timeout)
|
|
320
|
+
timeout = setTimeout(later, wait)
|
|
321
|
+
}]
|
|
322
|
+
},
|
|
323
|
+
|
|
324
|
+
window(el, cb) { return [window, cb] },
|
|
325
|
+
document(el, cb) { return [document, cb] },
|
|
326
|
+
outside(el, cb) {
|
|
327
|
+
return [el, (e) => {
|
|
328
|
+
if (el.contains(e.target)) return
|
|
329
|
+
if (e.target.isConnected === false) return
|
|
330
|
+
if (el.offsetWidth < 1 && el.offsetHeight < 1) return
|
|
331
|
+
cb(e)
|
|
332
|
+
}]
|
|
333
|
+
},
|
|
334
|
+
prevent(el, cb) { return [el, e => { e.preventDefault(); cb(e) } ]},
|
|
335
|
+
stop(el, cb) { return [el, e => { e.stopPropagation(); cb(e) } ]},
|
|
336
|
+
self(el, cb) { return [el, e => { e.target === el && cb(e) } ]},
|
|
337
|
+
once(el, cb, opts) { opts.once = true; return [el, cb] },
|
|
338
|
+
passive(el, cb, opts) { opts.passive = true; return [el, cb] },
|
|
339
|
+
capture(el, cb, opts) { opts.capture = true; return [el, cb] },
|
|
340
|
+
};
|
|
341
|
+
let keys = {
|
|
342
|
+
ctrl:'Control Ctrl',
|
|
343
|
+
shift:'Shift',
|
|
344
|
+
alt:'Alt',
|
|
345
|
+
meta:'Meta',cmd:'Meta',
|
|
346
|
+
down:'ArrowDown',up:'ArrowUp',left:'ArrowLeft',right:'ArrowRight',
|
|
347
|
+
end:'End',home:'Home',pagedown:'PageDown',pageup:'PageUp',
|
|
348
|
+
enter:'Enter',plus:'+',minus:'-',star:'*',slash:'/',period:'.',equal:'=',underscore:'_',
|
|
349
|
+
esc:'Escape',escape:'Escape',tab:'Tab',space:' ',
|
|
350
|
+
backspace:'Backspace', delete:'Delete'
|
|
351
|
+
}
|
|
352
|
+
for (let keyAttr in keys) {
|
|
353
|
+
let keyName = keys[keyAttr]
|
|
354
|
+
mods[keyAttr] = (el, cb, opts, extraKey) => [el, e => {
|
|
355
|
+
if (!e.key || !keyName.includes(e.key)) return
|
|
356
|
+
cb(e)
|
|
357
|
+
}]
|
|
284
358
|
}
|
|
285
359
|
|
|
286
360
|
// set attr
|
|
@@ -289,7 +363,6 @@ const attr = (el, name, v) => {
|
|
|
289
363
|
else el.setAttribute(name, v === true ? '' : (typeof v === 'number' || typeof v === 'string') ? v : '')
|
|
290
364
|
}
|
|
291
365
|
|
|
292
|
-
|
|
293
366
|
let evaluatorMemo = {}
|
|
294
367
|
|
|
295
368
|
// borrowed from alpine: https://github.com/alpinejs/alpine/blob/main/packages/alpinejs/src/evaluator.js#L61
|
|
@@ -326,7 +399,7 @@ function parseExpr(el, expression, dir) {
|
|
|
326
399
|
}
|
|
327
400
|
}
|
|
328
401
|
|
|
329
|
-
|
|
402
|
+
function exprError(error, element, expression, dir) {
|
|
330
403
|
Object.assign( error, { element, expression } )
|
|
331
404
|
console.warn(`∴ ${error.message}\n\n${dir}=${ expression ? `"${expression}"\n\n` : '' }`, element)
|
|
332
405
|
setTimeout(() => { throw error }, 0)
|
package/test/test.js
CHANGED
|
@@ -424,12 +424,16 @@ test.todo('each: unmounted elements remove listeners', async () => {
|
|
|
424
424
|
|
|
425
425
|
test('each: internal children get updated by state update, also: update by running again', () => {
|
|
426
426
|
let el = h`<><x :each="item, idx in items" :text="item" :key="idx"></x></>`
|
|
427
|
-
sprae(el, { items: [1,2,3] })
|
|
427
|
+
let state = sprae(el, { items: [1,2,3] })
|
|
428
428
|
is(el.textContent, '123')
|
|
429
|
-
|
|
429
|
+
state.items = [2, 2, 3]
|
|
430
|
+
is(el.textContent, '223')
|
|
431
|
+
state = sprae(el, { items: [0,2,3] })
|
|
430
432
|
is(el.textContent, '023')
|
|
433
|
+
// NOTE: this doesn't update items, since they're new array
|
|
434
|
+
console.log('set items')
|
|
431
435
|
state.items[0] = 1
|
|
432
|
-
state.items = state.items
|
|
436
|
+
state.items = [...state.items]
|
|
433
437
|
is(el.textContent, '123')
|
|
434
438
|
})
|
|
435
439
|
|
|
@@ -569,6 +573,57 @@ test('on: state changes between chain of events', e => {
|
|
|
569
573
|
is(log, [1, 1.1, 2])
|
|
570
574
|
})
|
|
571
575
|
|
|
576
|
+
test('on: once', e => {
|
|
577
|
+
// NOTE: if callback updates it's still rebound
|
|
578
|
+
let el = h`<x :onx.once="(e=>x&&log.push(this))" ></x>`
|
|
579
|
+
let log = []
|
|
580
|
+
let state = sprae(el, {log, x:1})
|
|
581
|
+
el.dispatchEvent(new window.Event('x'));
|
|
582
|
+
is(log, [el])
|
|
583
|
+
el.dispatchEvent(new window.Event('x'));
|
|
584
|
+
is(log, [el])
|
|
585
|
+
state.x = 2
|
|
586
|
+
el.dispatchEvent(new window.Event('x'));
|
|
587
|
+
el.dispatchEvent(new window.Event('x'));
|
|
588
|
+
is(log, [el])
|
|
589
|
+
})
|
|
590
|
+
|
|
591
|
+
test('on: capture, stop, prevent', e => {
|
|
592
|
+
let el = h`<x :onx.capture="e=>log.push(1)"><y :onx="e=>log.push(2)"></y></x>`
|
|
593
|
+
let state = sprae(el, {log:[]})
|
|
594
|
+
el.firstChild.dispatchEvent(new window.Event('x', {bubbles:true}));
|
|
595
|
+
is(state.log, [1,2])
|
|
596
|
+
|
|
597
|
+
let el2 = h`<x :onx="e=>log.push(1)"><y :onx.stop="e=>log.push(2)"></y></x>`
|
|
598
|
+
let state2 = sprae(el2, {log:[]})
|
|
599
|
+
el2.firstChild.dispatchEvent(new window.Event('x', {bubbles:true}));
|
|
600
|
+
is(state2.log, [2])
|
|
601
|
+
})
|
|
602
|
+
|
|
603
|
+
test('on: window, self', e => {
|
|
604
|
+
let el = h`<x :onx.self="e=>log.push(1)"><y :onx.window="e=>log.push(2)"></y></x>`
|
|
605
|
+
let state = sprae(el, {log:[]})
|
|
606
|
+
el.firstChild.dispatchEvent(new window.Event('x', {bubbles:true}));
|
|
607
|
+
is(state.log, [])
|
|
608
|
+
el.dispatchEvent(new window.Event('x', {bubbles:true}));
|
|
609
|
+
is(state.log, [1])
|
|
610
|
+
window.dispatchEvent(new window.Event('x', {bubbles:true}));
|
|
611
|
+
is(state.log, [1,2])
|
|
612
|
+
})
|
|
613
|
+
|
|
614
|
+
test('on: keys', e => {
|
|
615
|
+
let el = h`<x :onkeydown.enter="e=>log.push(1)"></x>`
|
|
616
|
+
let state = {log:[]}
|
|
617
|
+
sprae(el, state)
|
|
618
|
+
el.dispatchEvent(new window.KeyboardEvent('keydown', { key: '' }));
|
|
619
|
+
is(state.log,[])
|
|
620
|
+
el.dispatchEvent(new window.KeyboardEvent('keydown', { key: 'Enter' }));
|
|
621
|
+
el.dispatchEvent(new window.KeyboardEvent('keydown', { key: '' }));
|
|
622
|
+
is(state.log,[1])
|
|
623
|
+
el.dispatchEvent(new window.KeyboardEvent('keydown', { key: 'Enter' }));
|
|
624
|
+
is(state.log,[1,1])
|
|
625
|
+
})
|
|
626
|
+
|
|
572
627
|
test('with: inline', () => {
|
|
573
628
|
let el = h`<x :with="{foo:'bar'}"><y :text="foo + baz"></y></x>`
|
|
574
629
|
let state = sprae(el, {baz: 'qux'})
|