sprae 11.2.2 → 11.2.4
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/core.js +37 -36
- package/directive/default.js +4 -4
- package/directive/each.js +8 -6
- package/directive/if.js +2 -3
- package/dist/sprae.js +43 -55
- package/dist/sprae.js.map +2 -2
- package/dist/sprae.min.js +3 -3
- package/dist/sprae.min.js.map +3 -3
- package/dist/sprae.umd.js +64 -76
- package/dist/sprae.umd.js.map +3 -3
- package/dist/sprae.umd.min.js +2 -2
- package/dist/sprae.umd.min.js.map +3 -3
- package/package.json +1 -1
- package/readme.md +1 -1
- package/store.js +58 -65
package/core.js
CHANGED
|
@@ -2,12 +2,12 @@ import { use, effect } from "./signal.js";
|
|
|
2
2
|
import { store, _signals } from './store.js';
|
|
3
3
|
|
|
4
4
|
// polyfill
|
|
5
|
-
const _dispose = (Symbol.dispose ||= Symbol("dispose"));
|
|
5
|
+
export const _dispose = (Symbol.dispose ||= Symbol("dispose"));
|
|
6
6
|
|
|
7
7
|
export const _state = Symbol("state"), _on = Symbol('on'), _off = Symbol('off')
|
|
8
8
|
|
|
9
9
|
// registered directives
|
|
10
|
-
const directive = {}
|
|
10
|
+
export const directive = {}
|
|
11
11
|
|
|
12
12
|
/**
|
|
13
13
|
* Register a directive with a parsed expression and evaluator.
|
|
@@ -28,39 +28,39 @@ export const dir = (name, create, p = parse) => directive[name] = (el, expr, sta
|
|
|
28
28
|
* @param {Object} [values] - Initial values to populate the element's reactive state.
|
|
29
29
|
* @returns {Object} The reactive state object associated with the element.
|
|
30
30
|
*/
|
|
31
|
-
export
|
|
31
|
+
export const sprae = (el, values) => {
|
|
32
32
|
// repeated call can be caused by eg. :each with new objects with old keys
|
|
33
33
|
if (el[_state]) return Object.assign(el[_state], values)
|
|
34
34
|
|
|
35
35
|
// take over existing state instead of creating a clone
|
|
36
|
-
|
|
36
|
+
let state = store(values || {}), offs = [], fx = [],
|
|
37
37
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
38
|
+
init = (el, attrs = el.attributes) => {
|
|
39
|
+
// we iterate live collection (subsprae can init args)
|
|
40
|
+
if (attrs) for (let i = 0; i < attrs.length;) {
|
|
41
|
+
let { name, value } = attrs[i], pfx, update, dir
|
|
42
42
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
43
|
+
// if we have parts meaning there's attr needs to be spraed
|
|
44
|
+
// :id:name -> [,id,name]; s-text:id -> [,text,id]; ab-cd -> [ab-cd]
|
|
45
|
+
if (pfx = name[0] === ':' ? 1 : (name[0] === 's' && name[1] === '-') ? 2 : 0) {
|
|
46
|
+
el.removeAttribute(name);
|
|
47
47
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
48
|
+
// multiple attributes like :id:for=""
|
|
49
|
+
for (dir of name.slice(pfx).split(':')) {
|
|
50
|
+
update = (directive[dir] || directive.default)(el, value, state, dir)
|
|
51
51
|
|
|
52
|
-
|
|
53
|
-
|
|
52
|
+
// save & start effect
|
|
53
|
+
fx.push(update), offs.push(effect(update))
|
|
54
54
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
55
|
+
// stop after :each, :if, :with etc.
|
|
56
|
+
if (el[_state] === null) return
|
|
57
|
+
}
|
|
58
|
+
} else i++
|
|
59
|
+
}
|
|
60
60
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
61
|
+
// :if and :each replace element with text node, which tweaks .children length, but .childNodes length persists
|
|
62
|
+
for (let child of el.childNodes) child.nodeType == 1 && init(child)
|
|
63
|
+
};
|
|
64
64
|
|
|
65
65
|
init(el);
|
|
66
66
|
|
|
@@ -69,8 +69,8 @@ export default function sprae(el, values) {
|
|
|
69
69
|
el[_state] = state
|
|
70
70
|
|
|
71
71
|
// on/off all effects
|
|
72
|
-
el[_off] = () =>
|
|
73
|
-
el[_on] = () => offs
|
|
72
|
+
el[_off] = () => (offs.map(off => off()), offs = [])
|
|
73
|
+
el[_on] = () => offs = fx.map(f => effect(f))
|
|
74
74
|
|
|
75
75
|
// destroy
|
|
76
76
|
el[_dispose] = () => (el[_off](), el[_off] = el[_on] = el[_dispose] = el[_state] = null)
|
|
@@ -79,6 +79,13 @@ export default function sprae(el, values) {
|
|
|
79
79
|
return state;
|
|
80
80
|
}
|
|
81
81
|
|
|
82
|
+
// configure signals/compile
|
|
83
|
+
// it's more compact than using sprae.signal = signal etc.
|
|
84
|
+
sprae.use = s => {
|
|
85
|
+
s.signal && use(s);
|
|
86
|
+
s.compile && (compile = s.compile);
|
|
87
|
+
}
|
|
88
|
+
|
|
82
89
|
/**
|
|
83
90
|
* Parses an expression into an evaluator function, caching the result for reuse.
|
|
84
91
|
*
|
|
@@ -105,7 +112,7 @@ const memo = {};
|
|
|
105
112
|
* @param {string} [expr=''] - The expression associated with the error, if any.
|
|
106
113
|
* @throws {Error} The enhanced error object with a formatted message.
|
|
107
114
|
*/
|
|
108
|
-
export const err = (e, dir='', expr='') => {
|
|
115
|
+
export const err = (e, dir = '', expr = '') => {
|
|
109
116
|
throw Object.assign(e, { message: `∴ ${e.message}\n\n${dir}${expr ? `="${expr}"\n\n` : ""}`, expr })
|
|
110
117
|
}
|
|
111
118
|
|
|
@@ -116,14 +123,6 @@ export const err = (e, dir='', expr='') => {
|
|
|
116
123
|
*/
|
|
117
124
|
export let compile
|
|
118
125
|
|
|
119
|
-
// configure signals/compile
|
|
120
|
-
// it's more compact than using sprae.signal = signal etc.
|
|
121
|
-
sprae.use = s => {
|
|
122
|
-
s.signal && use(s);
|
|
123
|
-
s.compile && (compile = s.compile);
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
|
|
127
126
|
// instantiated <template> fragment holder, like persisting fragment but with minimal API surface
|
|
128
127
|
export const frag = (tpl) => {
|
|
129
128
|
if (!tpl.nodeType) return tpl // existing tpl
|
|
@@ -149,3 +148,5 @@ export const frag = (tpl) => {
|
|
|
149
148
|
// setAttributeNode() { }
|
|
150
149
|
}
|
|
151
150
|
}
|
|
151
|
+
|
|
152
|
+
export default sprae
|
package/directive/default.js
CHANGED
|
@@ -11,7 +11,7 @@ dir('default', (target, state, expr, name) => {
|
|
|
11
11
|
// bind event to a target
|
|
12
12
|
// NOTE: if you decide to remove chain of events, thing again - that's unique feature of sprae, don't diminish your own value.
|
|
13
13
|
// ona..onb
|
|
14
|
-
|
|
14
|
+
let ctxs = name.split('..').map(e => {
|
|
15
15
|
let ctx = { evt: '', target, test: () => true };
|
|
16
16
|
ctx.evt = (e.startsWith('on') ? e.slice(2) : e).replace(/\.(\w+)?-?([-\w]+)?/g,
|
|
17
17
|
(_, mod, param = '') => (ctx.test = mods[mod]?.(ctx, ...param.split('-')) || ctx.test, '')
|
|
@@ -20,10 +20,10 @@ dir('default', (target, state, expr, name) => {
|
|
|
20
20
|
});
|
|
21
21
|
|
|
22
22
|
// add listener with the context
|
|
23
|
-
|
|
23
|
+
let addListener = (fn, { evt, target, test, defer, stop, prevent, immediate, ...opts }, cb) => {
|
|
24
24
|
if (defer) fn = defer(fn)
|
|
25
25
|
|
|
26
|
-
|
|
26
|
+
cb = (e) => {
|
|
27
27
|
try {
|
|
28
28
|
test(e) && (stop && (immediate ? e.stopImmediatePropagation() : e.stopPropagation()), prevent && e.preventDefault(), fn?.call(state, e))
|
|
29
29
|
} catch (error) { err(error, `:on${evt}`, fn) }
|
|
@@ -38,7 +38,7 @@ dir('default', (target, state, expr, name) => {
|
|
|
38
38
|
|
|
39
39
|
// events cycler
|
|
40
40
|
let startFn, nextFn, off, idx = 0
|
|
41
|
-
|
|
41
|
+
let nextListener = (fn) => {
|
|
42
42
|
off = addListener((e) => (
|
|
43
43
|
off(), nextFn = fn?.(e), (idx = ++idx % ctxs.length) ? nextListener(nextFn) : (startFn && nextListener(startFn))
|
|
44
44
|
), ctxs[idx]);
|
package/directive/each.js
CHANGED
|
@@ -4,17 +4,15 @@ import { effect } from '../signal.js';
|
|
|
4
4
|
|
|
5
5
|
|
|
6
6
|
dir('each', (tpl, state, expr) => {
|
|
7
|
-
|
|
7
|
+
let [itemVar, idxVar = "$"] = expr.split(/\bin\b/)[0].trim().split(/\s*,\s*/);
|
|
8
8
|
|
|
9
9
|
// we need :if to be able to replace holder instead of tpl for :if :each case
|
|
10
|
-
|
|
11
|
-
tpl.replaceWith(holder);
|
|
12
|
-
tpl[_state] = null // mark as fake-spraed, to preserve :-attribs for template
|
|
10
|
+
let holder = document.createTextNode("");
|
|
13
11
|
|
|
14
12
|
// we re-create items any time new items are produced
|
|
15
13
|
let cur, keys, items, prevl = 0
|
|
16
14
|
|
|
17
|
-
|
|
15
|
+
let update = () => {
|
|
18
16
|
let i = 0, newItems = items, newl = newItems.length
|
|
19
17
|
|
|
20
18
|
// plain array update, not store (signal with array) - updates full list
|
|
@@ -56,7 +54,11 @@ dir('each', (tpl, state, expr) => {
|
|
|
56
54
|
prevl = newl
|
|
57
55
|
}
|
|
58
56
|
|
|
57
|
+
tpl.replaceWith(holder);
|
|
58
|
+
tpl[_state] = null // mark as fake-spraed, to preserve :-attribs for template
|
|
59
|
+
|
|
59
60
|
return value => {
|
|
61
|
+
// obtain new items
|
|
60
62
|
keys = null
|
|
61
63
|
if (typeof value === "number") items = Array.from({ length: value }, (_, i) => i + 1)
|
|
62
64
|
else if (value?.constructor === Object) keys = Object.keys(value), items = Object.values(value)
|
|
@@ -75,5 +77,5 @@ dir('each', (tpl, state, expr) => {
|
|
|
75
77
|
},
|
|
76
78
|
|
|
77
79
|
// redefine evaluator to take second part of expression
|
|
78
|
-
expr => parse(expr.split(/\
|
|
80
|
+
expr => parse(expr.split(/\bin\b/)[1])
|
|
79
81
|
)
|
package/directive/if.js
CHANGED
|
@@ -6,7 +6,7 @@ import sprae, { dir, _state, _on, _off, frag } from "../core.js";
|
|
|
6
6
|
const _prevIf = Symbol("if");
|
|
7
7
|
|
|
8
8
|
dir('if', (el, state) => {
|
|
9
|
-
|
|
9
|
+
let holder = document.createTextNode('')
|
|
10
10
|
|
|
11
11
|
let next = el.nextElementSibling,
|
|
12
12
|
curEl, ifEl, elseEl;
|
|
@@ -22,8 +22,7 @@ dir('if', (el, state) => {
|
|
|
22
22
|
if (!next.hasAttribute(":if")) next.remove(), elseEl = next.content ? frag(next) : next, elseEl[_state] = null
|
|
23
23
|
}
|
|
24
24
|
|
|
25
|
-
return (value) => {
|
|
26
|
-
const newEl = value ? ifEl : el[_prevIf] ? null : elseEl;
|
|
25
|
+
return (value, newEl = value ? ifEl : el[_prevIf] ? null : elseEl) => {
|
|
27
26
|
if (next) next[_prevIf] = newEl === ifEl
|
|
28
27
|
if (curEl != newEl) {
|
|
29
28
|
// disable effects on child elements when element is not matched
|
package/dist/sprae.js
CHANGED
|
@@ -42,34 +42,26 @@ var _signals = Symbol("signals");
|
|
|
42
42
|
var _change = Symbol("change");
|
|
43
43
|
var store = (values, parent) => {
|
|
44
44
|
if (!values) return values;
|
|
45
|
-
if (values[_signals]) return values;
|
|
46
|
-
if (Array.isArray(values)
|
|
47
|
-
|
|
48
|
-
let signals = { ...parent?.[_signals] }, _len = signal(Object.values(values).length);
|
|
49
|
-
const state = new Proxy(signals, {
|
|
45
|
+
if (values[_signals] || values[Symbol.toStringTag]) return values;
|
|
46
|
+
if (values.constructor !== Object) return Array.isArray(values) ? list(values) : values;
|
|
47
|
+
let signals = { ...parent?.[_signals] }, _len = signal(Object.values(values).length), state = new Proxy(signals, {
|
|
50
48
|
get: (_, key) => key === _change ? _len : key === _signals ? signals : signals[key]?.valueOf(),
|
|
51
49
|
set: (_, key, v, s) => (s = signals[key], set(signals, key, v), s ?? ++_len.value, 1),
|
|
52
50
|
// bump length for new signal
|
|
53
51
|
deleteProperty: (_, key) => (signals[key] && (signals[key][Symbol.dispose]?.(), delete signals[key], _len.value--), 1),
|
|
54
52
|
// subscribe to length when object is spread
|
|
55
53
|
ownKeys: () => (_len.value, Reflect.ownKeys(signals))
|
|
56
|
-
});
|
|
54
|
+
}), descs = Object.getOwnPropertyDescriptors(values), desc;
|
|
57
55
|
for (let key in values) {
|
|
58
|
-
|
|
59
|
-
if (desc?.get) {
|
|
56
|
+
if ((desc = descs[key])?.get)
|
|
60
57
|
(signals[key] = computed(desc.get.bind(state)))._set = desc.set?.bind(state);
|
|
61
|
-
|
|
62
|
-
signals[key] = null;
|
|
63
|
-
set(signals, key, values[key]);
|
|
64
|
-
}
|
|
58
|
+
else
|
|
59
|
+
signals[key] = null, set(signals, key, values[key]);
|
|
65
60
|
}
|
|
66
61
|
return state;
|
|
67
62
|
};
|
|
68
63
|
var list = (values) => {
|
|
69
|
-
let lastProp
|
|
70
|
-
if (values[_signals]) return values;
|
|
71
|
-
let _len = signal(values.length), signals = Array(values.length).fill();
|
|
72
|
-
const state = new Proxy(signals, {
|
|
64
|
+
let lastProp, _len = signal(values.length), signals = Array(values.length).fill(), state = new Proxy(signals, {
|
|
73
65
|
get(_, key) {
|
|
74
66
|
if (typeof key === "symbol") return key === _change ? _len : key === _signals ? signals : signals[key];
|
|
75
67
|
if (key === "length") return mut.includes(lastProp) ? _len.peek() : _len.value;
|
|
@@ -81,11 +73,11 @@ var list = (values) => {
|
|
|
81
73
|
if (key === "length") {
|
|
82
74
|
for (let i = v; i < signals.length; i++) delete state[i];
|
|
83
75
|
_len.value = signals.length = v;
|
|
84
|
-
|
|
76
|
+
} else {
|
|
77
|
+
set(signals, key, v);
|
|
78
|
+
if (key >= _len.peek()) _len.value = signals.length = +key + 1;
|
|
85
79
|
}
|
|
86
|
-
|
|
87
|
-
if (key >= _len.peek()) _len.value = signals.length = +key + 1;
|
|
88
|
-
return true;
|
|
80
|
+
return 1;
|
|
89
81
|
},
|
|
90
82
|
deleteProperty: (_, key) => (signals[key]?.[Symbol.dispose]?.(), delete signals[key], 1)
|
|
91
83
|
});
|
|
@@ -93,13 +85,12 @@ var list = (values) => {
|
|
|
93
85
|
};
|
|
94
86
|
var mut = ["push", "pop", "shift", "unshift", "splice"];
|
|
95
87
|
var set = (signals, key, v) => {
|
|
96
|
-
let s = signals[key];
|
|
88
|
+
let s = signals[key], cur;
|
|
97
89
|
if (key[0] === "_") signals[key] = v;
|
|
98
90
|
else if (!s) signals[key] = s = v?.peek ? v : signal(store(v));
|
|
99
|
-
else if (v === s.peek()) ;
|
|
91
|
+
else if (v === (cur = s.peek())) ;
|
|
100
92
|
else if (s._set) s._set(v);
|
|
101
|
-
else if (Array.isArray(v) && Array.isArray(
|
|
102
|
-
const cur = s.peek();
|
|
93
|
+
else if (Array.isArray(v) && Array.isArray(cur)) {
|
|
103
94
|
if (cur[_change]) batch(() => {
|
|
104
95
|
for (let i = 0; i < v.length; i++) cur[i] = v[i];
|
|
105
96
|
cur.length = v.length;
|
|
@@ -116,10 +107,9 @@ var _on = Symbol("on");
|
|
|
116
107
|
var _off = Symbol("off");
|
|
117
108
|
var directive = {};
|
|
118
109
|
var dir = (name, create, p = parse) => directive[name] = (el, expr, state, name2, update, evaluate) => (evaluate = p(expr), update = create(el, state, expr, name2, evaluate), () => update(evaluate(state)));
|
|
119
|
-
|
|
110
|
+
var sprae = (el, values) => {
|
|
120
111
|
if (el[_state]) return Object.assign(el[_state], values);
|
|
121
|
-
|
|
122
|
-
const init = (el2, attrs = el2.attributes) => {
|
|
112
|
+
let state = store(values || {}), offs = [], fx = [], init = (el2, attrs = el2.attributes) => {
|
|
123
113
|
if (attrs) for (let i = 0; i < attrs.length; ) {
|
|
124
114
|
let { name, value } = attrs[i], pfx, update, dir2;
|
|
125
115
|
if (pfx = name[0] === ":" ? 1 : name[0] === "s" && name[1] === "-" ? 2 : 0) {
|
|
@@ -136,14 +126,16 @@ function sprae(el, values) {
|
|
|
136
126
|
init(el);
|
|
137
127
|
if (!(_state in el)) {
|
|
138
128
|
el[_state] = state;
|
|
139
|
-
el[_off] = () =>
|
|
140
|
-
|
|
141
|
-
};
|
|
142
|
-
el[_on] = () => offs.push(...fx.map((f) => effect(f)));
|
|
129
|
+
el[_off] = () => (offs.map((off) => off()), offs = []);
|
|
130
|
+
el[_on] = () => offs = fx.map((f) => effect(f));
|
|
143
131
|
el[_dispose] = () => (el[_off](), el[_off] = el[_on] = el[_dispose] = el[_state] = null);
|
|
144
132
|
}
|
|
145
133
|
return state;
|
|
146
|
-
}
|
|
134
|
+
};
|
|
135
|
+
sprae.use = (s) => {
|
|
136
|
+
s.signal && use(s);
|
|
137
|
+
s.compile && (compile = s.compile);
|
|
138
|
+
};
|
|
147
139
|
var parse = (expr, dir2, fn) => {
|
|
148
140
|
if (fn = memo[expr = expr.trim()]) return fn;
|
|
149
141
|
try {
|
|
@@ -162,10 +154,6 @@ ${dir2}${expr ? `="${expr}"
|
|
|
162
154
|
` : ""}`, expr });
|
|
163
155
|
};
|
|
164
156
|
var compile;
|
|
165
|
-
sprae.use = (s) => {
|
|
166
|
-
s.signal && use(s);
|
|
167
|
-
s.compile && (compile = s.compile);
|
|
168
|
-
};
|
|
169
157
|
var frag = (tpl) => {
|
|
170
158
|
if (!tpl.nodeType) return tpl;
|
|
171
159
|
let content = tpl.content.cloneNode(true), attributes = [...tpl.attributes], ref = document.createTextNode(""), childNodes = (content.append(ref), [...content.childNodes]);
|
|
@@ -186,11 +174,12 @@ var frag = (tpl) => {
|
|
|
186
174
|
// setAttributeNode() { }
|
|
187
175
|
};
|
|
188
176
|
};
|
|
177
|
+
var core_default = sprae;
|
|
189
178
|
|
|
190
179
|
// directive/if.js
|
|
191
180
|
var _prevIf = Symbol("if");
|
|
192
181
|
dir("if", (el, state) => {
|
|
193
|
-
|
|
182
|
+
let holder = document.createTextNode("");
|
|
194
183
|
let next = el.nextElementSibling, curEl, ifEl, elseEl;
|
|
195
184
|
el.replaceWith(holder);
|
|
196
185
|
ifEl = el.content ? frag(el) : el;
|
|
@@ -199,14 +188,13 @@ dir("if", (el, state) => {
|
|
|
199
188
|
next.removeAttribute(":else");
|
|
200
189
|
if (!next.hasAttribute(":if")) next.remove(), elseEl = next.content ? frag(next) : next, elseEl[_state] = null;
|
|
201
190
|
}
|
|
202
|
-
return (value) => {
|
|
203
|
-
const newEl = value ? ifEl : el[_prevIf] ? null : elseEl;
|
|
191
|
+
return (value, newEl = value ? ifEl : el[_prevIf] ? null : elseEl) => {
|
|
204
192
|
if (next) next[_prevIf] = newEl === ifEl;
|
|
205
193
|
if (curEl != newEl) {
|
|
206
194
|
if (curEl) curEl.remove(), curEl[_off]?.();
|
|
207
195
|
if (curEl = newEl) {
|
|
208
196
|
holder.before(curEl.content || curEl);
|
|
209
|
-
curEl[_state] === null ? (delete curEl[_state],
|
|
197
|
+
curEl[_state] === null ? (delete curEl[_state], core_default(curEl, state)) : curEl[_on]();
|
|
210
198
|
}
|
|
211
199
|
}
|
|
212
200
|
};
|
|
@@ -216,12 +204,10 @@ dir("if", (el, state) => {
|
|
|
216
204
|
dir(
|
|
217
205
|
"each",
|
|
218
206
|
(tpl, state, expr) => {
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
tpl.replaceWith(holder);
|
|
222
|
-
tpl[_state] = null;
|
|
207
|
+
let [itemVar, idxVar = "$"] = expr.split(/\bin\b/)[0].trim().split(/\s*,\s*/);
|
|
208
|
+
let holder = document.createTextNode("");
|
|
223
209
|
let cur, keys2, items, prevl = 0;
|
|
224
|
-
|
|
210
|
+
let update = () => {
|
|
225
211
|
var _a, _b;
|
|
226
212
|
let i = 0, newItems = items, newl = newItems.length;
|
|
227
213
|
if (cur && !cur[_change]) {
|
|
@@ -239,7 +225,7 @@ dir(
|
|
|
239
225
|
[idxVar]: keys2 ? keys2[idx] : idx
|
|
240
226
|
}, state), el = tpl.content ? frag(tpl) : tpl.cloneNode(true);
|
|
241
227
|
holder.before(el.content || el);
|
|
242
|
-
|
|
228
|
+
core_default(el, scope);
|
|
243
229
|
((_b = cur[_a = _signals] || (cur[_a] = []))[i] || (_b[i] = {}))[Symbol.dispose] = () => {
|
|
244
230
|
el[Symbol.dispose]?.(), el.remove();
|
|
245
231
|
};
|
|
@@ -247,6 +233,8 @@ dir(
|
|
|
247
233
|
}
|
|
248
234
|
prevl = newl;
|
|
249
235
|
};
|
|
236
|
+
tpl.replaceWith(holder);
|
|
237
|
+
tpl[_state] = null;
|
|
250
238
|
return (value) => {
|
|
251
239
|
keys2 = null;
|
|
252
240
|
if (typeof value === "number") items = Array.from({ length: value }, (_, i) => i + 1);
|
|
@@ -260,7 +248,7 @@ dir(
|
|
|
260
248
|
};
|
|
261
249
|
},
|
|
262
250
|
// redefine evaluator to take second part of expression
|
|
263
|
-
(expr) => parse(expr.split(/\
|
|
251
|
+
(expr) => parse(expr.split(/\bin\b/)[1])
|
|
264
252
|
);
|
|
265
253
|
|
|
266
254
|
// directive/default.js
|
|
@@ -269,7 +257,7 @@ dir("default", (target, state, expr, name) => {
|
|
|
269
257
|
return name ? (value) => attr(target, name, value) : (value) => {
|
|
270
258
|
for (let key in value) attr(target, dashcase(key), value[key]);
|
|
271
259
|
};
|
|
272
|
-
|
|
260
|
+
let ctxs = name.split("..").map((e) => {
|
|
273
261
|
let ctx = { evt: "", target, test: () => true };
|
|
274
262
|
ctx.evt = (e.startsWith("on") ? e.slice(2) : e).replace(
|
|
275
263
|
/\.(\w+)?-?([-\w]+)?/g,
|
|
@@ -277,9 +265,9 @@ dir("default", (target, state, expr, name) => {
|
|
|
277
265
|
);
|
|
278
266
|
return ctx;
|
|
279
267
|
});
|
|
280
|
-
|
|
268
|
+
let addListener = (fn, { evt, target: target2, test, defer, stop, prevent, immediate, ...opts }, cb) => {
|
|
281
269
|
if (defer) fn = defer(fn);
|
|
282
|
-
|
|
270
|
+
cb = (e) => {
|
|
283
271
|
try {
|
|
284
272
|
test(e) && (stop && (immediate ? e.stopImmediatePropagation() : e.stopPropagation()), prevent && e.preventDefault(), fn?.call(state, e));
|
|
285
273
|
} catch (error) {
|
|
@@ -291,7 +279,7 @@ dir("default", (target, state, expr, name) => {
|
|
|
291
279
|
};
|
|
292
280
|
if (ctxs.length == 1) return (v) => addListener(v, ctxs[0]);
|
|
293
281
|
let startFn, nextFn, off, idx = 0;
|
|
294
|
-
|
|
282
|
+
let nextListener = (fn) => {
|
|
295
283
|
off = addListener((e) => (off(), nextFn = fn?.(e), (idx = ++idx % ctxs.length) ? nextListener(nextFn) : startFn && nextListener(startFn)), ctxs[idx]);
|
|
296
284
|
};
|
|
297
285
|
return (value) => (startFn = value, !off && nextListener(startFn), () => startFn = null);
|
|
@@ -425,7 +413,7 @@ dir("value", (el, state, expr) => {
|
|
|
425
413
|
el.oninput = el.onchange = handleChange;
|
|
426
414
|
if (el.type?.startsWith("select")) {
|
|
427
415
|
new MutationObserver(handleChange).observe(el, { childList: true, subtree: true, attributes: true });
|
|
428
|
-
|
|
416
|
+
core_default(el, state);
|
|
429
417
|
}
|
|
430
418
|
} catch {
|
|
431
419
|
}
|
|
@@ -444,7 +432,7 @@ var ensure = (state, expr, name = expr.match(/^\w+(?=\s*(?:\.|\[|$))/)) => {
|
|
|
444
432
|
dir("ref", (el, state, expr, _, ev) => (ensure(state, expr), ev(state) == null ? (setter(expr)(state, el), (_2) => _2) : (v) => v.call(null, el)));
|
|
445
433
|
|
|
446
434
|
// directive/with.js
|
|
447
|
-
dir("with", (el, rootState, state) => (state = null, (values) =>
|
|
435
|
+
dir("with", (el, rootState, state) => (state = null, (values) => core_default(el, state ? values : state = store_default(values, rootState))));
|
|
448
436
|
|
|
449
437
|
// directive/text.js
|
|
450
438
|
dir("text", (el) => (
|
|
@@ -494,8 +482,8 @@ dir("data", (el) => (value) => {
|
|
|
494
482
|
});
|
|
495
483
|
|
|
496
484
|
// sprae.js
|
|
497
|
-
|
|
498
|
-
var sprae_default =
|
|
485
|
+
core_default.use({ compile: (expr) => core_default.constructor(`with (arguments[0]) { return ${expr} };`) });
|
|
486
|
+
var sprae_default = core_default;
|
|
499
487
|
export {
|
|
500
488
|
sprae_default as default
|
|
501
489
|
};
|