@estjs/template 0.0.16-beta.1 → 0.0.16-beta.3
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/dist/{chunk-3E4EK64L.dev.esm.js → chunk-JT6RSDKI.dev.esm.js} +11 -11
- package/dist/chunk-JT6RSDKI.dev.esm.js.map +1 -0
- package/dist/chunk-WWGSC3TY.esm.js +2 -0
- package/dist/chunk-WWGSC3TY.esm.js.map +1 -0
- package/dist/{internal-Bz6h0aPa.d.cts → internal-DSKAj-zW.d.cts} +4 -0
- package/dist/{internal-Bz6h0aPa.d.ts → internal-DSKAj-zW.d.ts} +4 -0
- package/dist/internal.cjs.js +1 -1
- package/dist/internal.cjs.js.map +1 -1
- package/dist/internal.d.cts +2 -1
- package/dist/internal.d.ts +2 -1
- package/dist/internal.dev.cjs.js +9 -9
- package/dist/internal.dev.cjs.js.map +1 -1
- package/dist/internal.dev.esm.js +1 -1
- package/dist/internal.esm.js +1 -1
- package/dist/template.cjs.js +2 -2
- package/dist/template.cjs.js.map +1 -1
- package/dist/template.d.cts +16 -13
- package/dist/template.d.ts +16 -13
- package/dist/template.dev.cjs.js +134 -134
- package/dist/template.dev.cjs.js.map +1 -1
- package/dist/template.dev.esm.js +126 -125
- package/dist/template.dev.esm.js.map +1 -1
- package/dist/template.esm.js +2 -2
- package/dist/template.esm.js.map +1 -1
- package/package.json +7 -3
- package/dist/chunk-3E4EK64L.dev.esm.js.map +0 -1
- package/dist/chunk-IRDMO5MX.esm.js +0 -2
- package/dist/chunk-IRDMO5MX.esm.js.map +0 -1
package/dist/template.d.cts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Signal, Computed } from '@estjs/signals';
|
|
2
|
-
import { S as Scope } from './internal-
|
|
3
|
-
export { I as InjectionKey, i as inject, p as provide } from './internal-
|
|
2
|
+
import { S as Scope } from './internal-DSKAj-zW.cjs';
|
|
3
|
+
export { I as InjectionKey, i as inject, p as provide } from './internal-DSKAj-zW.cjs';
|
|
4
4
|
import { normalizeClassName } from '@estjs/shared';
|
|
5
5
|
|
|
6
6
|
declare enum COMPONENT_STATE {
|
|
@@ -168,11 +168,11 @@ declare function onUpdate(hook: LifecycleHook): void;
|
|
|
168
168
|
declare function onDestroy(hook: LifecycleHook): void;
|
|
169
169
|
|
|
170
170
|
/**
|
|
171
|
-
* Modifiers
|
|
171
|
+
* Modifiers for `bind:*` two-way bindings.
|
|
172
172
|
*
|
|
173
|
-
* - `trim` strip surrounding whitespace
|
|
174
|
-
* - `number` coerce numeric strings to numbers (no-op on
|
|
175
|
-
* - `lazy` commit on `change` instead of `input`
|
|
173
|
+
* - `trim` — strip surrounding whitespace
|
|
174
|
+
* - `number` — coerce numeric strings to numbers (no-op on NaN)
|
|
175
|
+
* - `lazy` — commit on `change` instead of `input`
|
|
176
176
|
*/
|
|
177
177
|
interface BindModifiers {
|
|
178
178
|
trim?: boolean;
|
|
@@ -181,15 +181,18 @@ interface BindModifiers {
|
|
|
181
181
|
[key: string]: boolean | undefined;
|
|
182
182
|
}
|
|
183
183
|
/**
|
|
184
|
-
*
|
|
184
|
+
* Creates a two-way binding between a DOM element property and a reactive model.
|
|
185
185
|
*
|
|
186
|
-
*
|
|
187
|
-
*
|
|
188
|
-
*
|
|
189
|
-
* @param
|
|
190
|
-
* @param
|
|
186
|
+
* - **Model → DOM** — a reactive `effect()` pushes model changes to the element.
|
|
187
|
+
* - **DOM → Model** — an event listener reads user input and calls `setter`.
|
|
188
|
+
*
|
|
189
|
+
* @param node Target element. `null` is tolerated (no-op).
|
|
190
|
+
* @param prop Bound property (`value` / `checked` / `files` / custom).
|
|
191
|
+
* @param getter Reactive getter, or a static initial value.
|
|
192
|
+
* @param setter Called with the (optionally transformed) DOM value on user input.
|
|
193
|
+
* @param modifiers Optional `{ trim, number, lazy }`.
|
|
191
194
|
*/
|
|
192
|
-
declare function bindElement(node: Element | null, prop: 'value' | 'checked' | 'files' | string, getter: (() => unknown) | unknown, setter: (
|
|
195
|
+
declare function bindElement(node: Element | null, prop: 'value' | 'checked' | 'files' | string, getter: (() => unknown) | unknown, setter: (v: unknown) => void, modifiers?: BindModifiers): void;
|
|
193
196
|
|
|
194
197
|
/**
|
|
195
198
|
* Set up event delegation for specified event types.
|
package/dist/template.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Signal, Computed } from '@estjs/signals';
|
|
2
|
-
import { S as Scope } from './internal-
|
|
3
|
-
export { I as InjectionKey, i as inject, p as provide } from './internal-
|
|
2
|
+
import { S as Scope } from './internal-DSKAj-zW.js';
|
|
3
|
+
export { I as InjectionKey, i as inject, p as provide } from './internal-DSKAj-zW.js';
|
|
4
4
|
import { normalizeClassName } from '@estjs/shared';
|
|
5
5
|
|
|
6
6
|
declare enum COMPONENT_STATE {
|
|
@@ -168,11 +168,11 @@ declare function onUpdate(hook: LifecycleHook): void;
|
|
|
168
168
|
declare function onDestroy(hook: LifecycleHook): void;
|
|
169
169
|
|
|
170
170
|
/**
|
|
171
|
-
* Modifiers
|
|
171
|
+
* Modifiers for `bind:*` two-way bindings.
|
|
172
172
|
*
|
|
173
|
-
* - `trim` strip surrounding whitespace
|
|
174
|
-
* - `number` coerce numeric strings to numbers (no-op on
|
|
175
|
-
* - `lazy` commit on `change` instead of `input`
|
|
173
|
+
* - `trim` — strip surrounding whitespace
|
|
174
|
+
* - `number` — coerce numeric strings to numbers (no-op on NaN)
|
|
175
|
+
* - `lazy` — commit on `change` instead of `input`
|
|
176
176
|
*/
|
|
177
177
|
interface BindModifiers {
|
|
178
178
|
trim?: boolean;
|
|
@@ -181,15 +181,18 @@ interface BindModifiers {
|
|
|
181
181
|
[key: string]: boolean | undefined;
|
|
182
182
|
}
|
|
183
183
|
/**
|
|
184
|
-
*
|
|
184
|
+
* Creates a two-way binding between a DOM element property and a reactive model.
|
|
185
185
|
*
|
|
186
|
-
*
|
|
187
|
-
*
|
|
188
|
-
*
|
|
189
|
-
* @param
|
|
190
|
-
* @param
|
|
186
|
+
* - **Model → DOM** — a reactive `effect()` pushes model changes to the element.
|
|
187
|
+
* - **DOM → Model** — an event listener reads user input and calls `setter`.
|
|
188
|
+
*
|
|
189
|
+
* @param node Target element. `null` is tolerated (no-op).
|
|
190
|
+
* @param prop Bound property (`value` / `checked` / `files` / custom).
|
|
191
|
+
* @param getter Reactive getter, or a static initial value.
|
|
192
|
+
* @param setter Called with the (optionally transformed) DOM value on user input.
|
|
193
|
+
* @param modifiers Optional `{ trim, number, lazy }`.
|
|
191
194
|
*/
|
|
192
|
-
declare function bindElement(node: Element | null, prop: 'value' | 'checked' | 'files' | string, getter: (() => unknown) | unknown, setter: (
|
|
195
|
+
declare function bindElement(node: Element | null, prop: 'value' | 'checked' | 'files' | string, getter: (() => unknown) | unknown, setter: (v: unknown) => void, modifiers?: BindModifiers): void;
|
|
193
196
|
|
|
194
197
|
/**
|
|
195
198
|
* Set up event delegation for specified event types.
|
package/dist/template.dev.cjs.js
CHANGED
|
@@ -19,7 +19,7 @@ var __objRest = (source, exclude) => {
|
|
|
19
19
|
return target;
|
|
20
20
|
};
|
|
21
21
|
var __async = (__this, __arguments, generator) => {
|
|
22
|
-
return new Promise((
|
|
22
|
+
return new Promise((resolve2, reject) => {
|
|
23
23
|
var fulfilled = (value) => {
|
|
24
24
|
try {
|
|
25
25
|
step(generator.next(value));
|
|
@@ -34,7 +34,7 @@ var __async = (__this, __arguments, generator) => {
|
|
|
34
34
|
reject(e);
|
|
35
35
|
}
|
|
36
36
|
};
|
|
37
|
-
var step = (x) => x.done ?
|
|
37
|
+
var step = (x) => x.done ? resolve2(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
|
|
38
38
|
step((generator = generator.apply(__this, __arguments)).next());
|
|
39
39
|
});
|
|
40
40
|
};
|
|
@@ -56,8 +56,10 @@ function getActiveScope() {
|
|
|
56
56
|
return activeScope;
|
|
57
57
|
}
|
|
58
58
|
function createScope(parent = activeScope) {
|
|
59
|
+
const reactiveScope = parent ? parent.effectScope.run(() => signals.effectScope()) : signals.effectScope(true);
|
|
59
60
|
const scope = {
|
|
60
61
|
id: ++scopeId,
|
|
62
|
+
effectScope: reactiveScope,
|
|
61
63
|
parent,
|
|
62
64
|
children: null,
|
|
63
65
|
// Lazy initialized
|
|
@@ -86,7 +88,7 @@ function runWithScope(scope, fn) {
|
|
|
86
88
|
const prevScope = activeScope;
|
|
87
89
|
activeScope = scope;
|
|
88
90
|
try {
|
|
89
|
-
return fn
|
|
91
|
+
return scope.effectScope.run(fn);
|
|
90
92
|
} finally {
|
|
91
93
|
activeScope = prevScope;
|
|
92
94
|
}
|
|
@@ -106,15 +108,13 @@ function disposeScope(scope) {
|
|
|
106
108
|
}
|
|
107
109
|
scope.children.clear();
|
|
108
110
|
}
|
|
109
|
-
|
|
110
|
-
activeScope = scope;
|
|
111
|
-
try {
|
|
111
|
+
runWithScope(scope, () => {
|
|
112
112
|
if (scope.onDestroy) {
|
|
113
113
|
for (let i = 0; i < scope.onDestroy.length; i++) {
|
|
114
114
|
try {
|
|
115
115
|
scope.onDestroy[i]();
|
|
116
116
|
} catch (error_) {
|
|
117
|
-
|
|
117
|
+
{
|
|
118
118
|
shared.error(`Scope(${scope.id}): Error in destroy hook:`, error_);
|
|
119
119
|
}
|
|
120
120
|
}
|
|
@@ -126,16 +126,15 @@ function disposeScope(scope) {
|
|
|
126
126
|
try {
|
|
127
127
|
scope.cleanup[i]();
|
|
128
128
|
} catch (error_) {
|
|
129
|
-
|
|
129
|
+
{
|
|
130
130
|
shared.error(`Scope(${scope.id}): Error in cleanup:`, error_);
|
|
131
131
|
}
|
|
132
132
|
}
|
|
133
133
|
}
|
|
134
134
|
scope.cleanup = null;
|
|
135
135
|
}
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
}
|
|
136
|
+
});
|
|
137
|
+
scope.effectScope.stop();
|
|
139
138
|
if ((_a2 = scope.parent) == null ? void 0 : _a2.children) {
|
|
140
139
|
scope.parent.children.delete(scope);
|
|
141
140
|
}
|
|
@@ -207,7 +206,7 @@ function patchAttr(el, key, prev, next2) {
|
|
|
207
206
|
const elementIsSVG = (el == null ? void 0 : el.namespaceURI) === SVG_NAMESPACE;
|
|
208
207
|
const isXlink = elementIsSVG && key.startsWith("xlink:");
|
|
209
208
|
const isXmlns = elementIsSVG && key.startsWith("xmlns:");
|
|
210
|
-
const
|
|
209
|
+
const isBoolean = shared.isSpecialBooleanAttr(key) || shared.isBooleanAttr(key);
|
|
211
210
|
if (prev === next2) {
|
|
212
211
|
return;
|
|
213
212
|
}
|
|
@@ -232,7 +231,7 @@ function patchAttr(el, key, prev, next2) {
|
|
|
232
231
|
}
|
|
233
232
|
return;
|
|
234
233
|
}
|
|
235
|
-
if (
|
|
234
|
+
if (isBoolean) {
|
|
236
235
|
if (shared.includeBooleanAttr(next2)) {
|
|
237
236
|
el.setAttribute(key, "");
|
|
238
237
|
} else {
|
|
@@ -676,22 +675,30 @@ function insertNode(parent, child2, before) {
|
|
|
676
675
|
}
|
|
677
676
|
}
|
|
678
677
|
function normalizeNode(node) {
|
|
679
|
-
if (
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
if (
|
|
683
|
-
return document.createTextNode(
|
|
678
|
+
if (node instanceof Node) return node;
|
|
679
|
+
if (isComponent(node)) return node;
|
|
680
|
+
const t = typeof node;
|
|
681
|
+
if (node == null || t === "string" || t === "number" || t === "boolean" || t === "symbol") {
|
|
682
|
+
return document.createTextNode(node === false || node == null ? "" : String(node));
|
|
683
|
+
}
|
|
684
|
+
if (shared.isObject(node)) {
|
|
685
|
+
shared.warn(
|
|
686
|
+
"Rendering a plain object as a node is not recommended. The object will be converted to its string representation.",
|
|
687
|
+
node
|
|
688
|
+
);
|
|
684
689
|
}
|
|
685
|
-
return node;
|
|
690
|
+
return document.createTextNode(String(node));
|
|
686
691
|
}
|
|
687
692
|
function insert(parent, nodeFactory, before) {
|
|
688
693
|
if (!parent) return;
|
|
689
|
-
const
|
|
694
|
+
const parentScope = getActiveScope();
|
|
690
695
|
let renderedNodes = [];
|
|
691
696
|
let isFirstRun = true;
|
|
692
697
|
const resolveNodes = (raw) => {
|
|
693
698
|
if (raw instanceof Node) return [raw];
|
|
694
|
-
if (
|
|
699
|
+
if (isComponent(raw)) return [raw];
|
|
700
|
+
const t = typeof raw;
|
|
701
|
+
if (raw == null || t === "string" || t === "number" || t === "boolean") {
|
|
695
702
|
return [normalizeNode(raw)];
|
|
696
703
|
}
|
|
697
704
|
return shared.coerceArray(raw).map((item) => shared.isFunction(item) ? item() : item).flatMap((i) => i).map(normalizeNode);
|
|
@@ -708,8 +715,8 @@ function insert(parent, nodeFactory, before) {
|
|
|
708
715
|
renderedNodes = reconcileArrays(parent, renderedNodes, nodes, before);
|
|
709
716
|
isFirstRun = false;
|
|
710
717
|
};
|
|
711
|
-
if (
|
|
712
|
-
runWithScope(
|
|
718
|
+
if (parentScope && !parentScope.isDestroyed) {
|
|
719
|
+
runWithScope(parentScope, executeUpdate);
|
|
713
720
|
} else {
|
|
714
721
|
executeUpdate();
|
|
715
722
|
}
|
|
@@ -910,7 +917,9 @@ var Component = class {
|
|
|
910
917
|
if (shared.isFunction(result)) {
|
|
911
918
|
result = result(this.reactiveProps);
|
|
912
919
|
}
|
|
913
|
-
if (signals.isSignal(result)
|
|
920
|
+
if (signals.isSignal(result)) {
|
|
921
|
+
result = result.value;
|
|
922
|
+
} else if (signals.isComputed(result)) {
|
|
914
923
|
result = result.value;
|
|
915
924
|
}
|
|
916
925
|
return (_a3 = insert(parentNode, result, beforeNode)) != null ? _a3 : [];
|
|
@@ -1011,11 +1020,12 @@ var Component = class {
|
|
|
1011
1020
|
return () => value(null);
|
|
1012
1021
|
}
|
|
1013
1022
|
if (signals.isSignal(value)) {
|
|
1014
|
-
const
|
|
1015
|
-
|
|
1023
|
+
const ref = value;
|
|
1024
|
+
const previousValue = ref.value;
|
|
1025
|
+
ref.value = root;
|
|
1016
1026
|
return () => {
|
|
1017
|
-
if (
|
|
1018
|
-
|
|
1027
|
+
if (ref.value === root) {
|
|
1028
|
+
ref.value = previousValue;
|
|
1019
1029
|
}
|
|
1020
1030
|
};
|
|
1021
1031
|
}
|
|
@@ -1230,154 +1240,144 @@ function addEventListener(element, event, handler, options) {
|
|
|
1230
1240
|
}
|
|
1231
1241
|
|
|
1232
1242
|
// src/binding.ts
|
|
1233
|
-
|
|
1243
|
+
function writeValue(el, v) {
|
|
1244
|
+
const target = el;
|
|
1245
|
+
const next2 = v == null ? "" : String(v);
|
|
1246
|
+
if (target.value !== next2) target.value = next2;
|
|
1247
|
+
}
|
|
1248
|
+
var CHECKBOX = {
|
|
1234
1249
|
event: "change",
|
|
1235
|
-
|
|
1236
|
-
read: (
|
|
1237
|
-
write
|
|
1238
|
-
const
|
|
1250
|
+
forceChange: true,
|
|
1251
|
+
read: (el) => el.checked,
|
|
1252
|
+
write(el, v) {
|
|
1253
|
+
const e = el;
|
|
1239
1254
|
const next2 = Boolean(v);
|
|
1240
|
-
if (
|
|
1255
|
+
if (e.checked !== next2) e.checked = next2;
|
|
1241
1256
|
}
|
|
1242
1257
|
};
|
|
1243
|
-
var
|
|
1258
|
+
var RADIO = {
|
|
1244
1259
|
event: "change",
|
|
1245
|
-
|
|
1246
|
-
read
|
|
1247
|
-
const
|
|
1248
|
-
return
|
|
1260
|
+
forceChange: true,
|
|
1261
|
+
read(el) {
|
|
1262
|
+
const e = el;
|
|
1263
|
+
return e.checked ? e.value : "";
|
|
1249
1264
|
},
|
|
1250
|
-
write
|
|
1251
|
-
const
|
|
1252
|
-
const next2 = String(v) ===
|
|
1253
|
-
if (
|
|
1265
|
+
write(el, v) {
|
|
1266
|
+
const e = el;
|
|
1267
|
+
const next2 = String(v) === e.value;
|
|
1268
|
+
if (e.checked !== next2) e.checked = next2;
|
|
1254
1269
|
}
|
|
1255
1270
|
};
|
|
1256
|
-
var
|
|
1271
|
+
var FILE = {
|
|
1257
1272
|
event: "change",
|
|
1258
|
-
|
|
1259
|
-
read: (
|
|
1260
|
-
|
|
1261
|
-
write: () => {
|
|
1273
|
+
forceChange: true,
|
|
1274
|
+
read: (el) => el.files,
|
|
1275
|
+
write() {
|
|
1262
1276
|
}
|
|
1277
|
+
// browsers forbid programmatic writes to file inputs
|
|
1263
1278
|
};
|
|
1264
|
-
var
|
|
1279
|
+
var TEXT = {
|
|
1265
1280
|
event: "input",
|
|
1266
|
-
|
|
1267
|
-
read: (
|
|
1268
|
-
write:
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1281
|
+
ime: true,
|
|
1282
|
+
read: (el) => el.value,
|
|
1283
|
+
write: writeValue
|
|
1284
|
+
};
|
|
1285
|
+
var TEXTAREA = {
|
|
1286
|
+
event: "input",
|
|
1287
|
+
ime: true,
|
|
1288
|
+
read: (el) => el.value,
|
|
1289
|
+
write: writeValue
|
|
1273
1290
|
};
|
|
1274
|
-
var
|
|
1291
|
+
var SELECT = {
|
|
1275
1292
|
event: "change",
|
|
1276
|
-
|
|
1277
|
-
read
|
|
1278
|
-
const s =
|
|
1293
|
+
forceChange: true,
|
|
1294
|
+
read(el) {
|
|
1295
|
+
const s = el;
|
|
1279
1296
|
return s.multiple ? Array.from(s.selectedOptions, (o) => o.value) : s.value;
|
|
1280
1297
|
},
|
|
1281
|
-
write
|
|
1282
|
-
const s =
|
|
1298
|
+
write(el, v) {
|
|
1299
|
+
const s = el;
|
|
1283
1300
|
if (s.multiple) {
|
|
1284
|
-
const
|
|
1285
|
-
for (const opt of Array.from(s.options)) opt.selected =
|
|
1301
|
+
const selected = new Set((Array.isArray(v) ? v : []).map(String));
|
|
1302
|
+
for (const opt of Array.from(s.options)) opt.selected = selected.has(opt.value);
|
|
1286
1303
|
} else {
|
|
1287
|
-
|
|
1288
|
-
if (s.value !== next2) s.value = next2;
|
|
1304
|
+
writeValue(el, v);
|
|
1289
1305
|
}
|
|
1290
1306
|
}
|
|
1291
1307
|
};
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
|
|
1308
|
+
function resolve(node, prop) {
|
|
1309
|
+
switch (node.nodeName) {
|
|
1310
|
+
case "INPUT":
|
|
1311
|
+
if (prop === "checked") return node.type === "radio" ? RADIO : CHECKBOX;
|
|
1312
|
+
if (prop === "files") return FILE;
|
|
1313
|
+
return TEXT;
|
|
1314
|
+
case "SELECT":
|
|
1315
|
+
return SELECT;
|
|
1316
|
+
case "TEXTAREA":
|
|
1317
|
+
return TEXTAREA;
|
|
1318
|
+
default:
|
|
1319
|
+
return {
|
|
1320
|
+
event: "input",
|
|
1321
|
+
read: (el) => el[prop],
|
|
1322
|
+
write(el, v) {
|
|
1323
|
+
el[prop] = v;
|
|
1324
|
+
}
|
|
1325
|
+
};
|
|
1300
1326
|
}
|
|
1301
|
-
};
|
|
1302
|
-
function resolveStrategy(node, prop) {
|
|
1303
|
-
const tag = node.nodeName;
|
|
1304
|
-
if (tag === "INPUT") {
|
|
1305
|
-
const type = node.type;
|
|
1306
|
-
if (prop === "checked") {
|
|
1307
|
-
return type === "radio" ? INPUT_RADIO_CHECKED : INPUT_CHECKBOX_CHECKED;
|
|
1308
|
-
}
|
|
1309
|
-
if (prop === "files") return INPUT_FILE_FILES;
|
|
1310
|
-
return INPUT_VALUE;
|
|
1311
|
-
}
|
|
1312
|
-
if (tag === "SELECT") return SELECT_VALUE;
|
|
1313
|
-
if (tag === "TEXTAREA") return TEXTAREA_VALUE;
|
|
1314
|
-
return {
|
|
1315
|
-
event: "input",
|
|
1316
|
-
read: (n) => n[prop],
|
|
1317
|
-
write: (n, v) => {
|
|
1318
|
-
n[prop] = v;
|
|
1319
|
-
}
|
|
1320
|
-
};
|
|
1321
1327
|
}
|
|
1322
|
-
function
|
|
1323
|
-
if (!shared.isString(
|
|
1324
|
-
|
|
1325
|
-
if (
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
+
function applyModifiers(v, trim, toNum) {
|
|
1329
|
+
if (!shared.isString(v)) return v;
|
|
1330
|
+
let s = v;
|
|
1331
|
+
if (trim) s = s.trim();
|
|
1332
|
+
if (toNum && s !== "") {
|
|
1333
|
+
const n = Number(s);
|
|
1334
|
+
if (!Number.isNaN(n)) return n;
|
|
1328
1335
|
}
|
|
1329
|
-
return
|
|
1336
|
+
return s;
|
|
1330
1337
|
}
|
|
1331
|
-
function isFocused(
|
|
1332
|
-
const root =
|
|
1333
|
-
return (root instanceof Document || root instanceof ShadowRoot) && root.activeElement ===
|
|
1338
|
+
function isFocused(el) {
|
|
1339
|
+
const root = el.getRootNode();
|
|
1340
|
+
return (root instanceof Document || root instanceof ShadowRoot) && root.activeElement === el;
|
|
1334
1341
|
}
|
|
1335
1342
|
function bindElement(node, prop, getter, setter, modifiers = {}) {
|
|
1336
1343
|
if (!node) return;
|
|
1337
|
-
const
|
|
1338
|
-
const
|
|
1339
|
-
const
|
|
1340
|
-
const
|
|
1341
|
-
const
|
|
1342
|
-
const
|
|
1344
|
+
const { event, read, write, forceChange, ime } = resolve(node, prop);
|
|
1345
|
+
const trim = modifiers.trim === true;
|
|
1346
|
+
const toNum = modifiers.number === true;
|
|
1347
|
+
const lazy = modifiers.lazy === true;
|
|
1348
|
+
const shouldCast = (trim || toNum) && prop !== "files";
|
|
1349
|
+
const getModel = shared.isFunction(getter) ? getter : () => getter;
|
|
1350
|
+
const cast = shouldCast ? (v) => applyModifiers(v, trim, toNum) : (v) => v;
|
|
1343
1351
|
let composing = false;
|
|
1344
|
-
const
|
|
1352
|
+
const eventName = lazy || forceChange ? "change" : event;
|
|
1353
|
+
const syncToModel = () => {
|
|
1345
1354
|
if (composing) return;
|
|
1346
|
-
const raw =
|
|
1355
|
+
const raw = read(node);
|
|
1347
1356
|
if (raw === void 0) return;
|
|
1348
|
-
|
|
1349
|
-
|
|
1350
|
-
return;
|
|
1351
|
-
}
|
|
1352
|
-
const next2 = transform(raw);
|
|
1353
|
-
if (!Object.is(readModel(), next2)) {
|
|
1354
|
-
setter(next2);
|
|
1355
|
-
}
|
|
1357
|
+
const next2 = cast(raw);
|
|
1358
|
+
if (!Object.is(getModel(), next2)) setter(next2);
|
|
1356
1359
|
};
|
|
1357
|
-
addEventListener(node, eventName,
|
|
1358
|
-
if (!lazy &&
|
|
1359
|
-
addEventListener(node, "change", () =>
|
|
1360
|
-
strategy.write(node, transform(strategy.read(node)));
|
|
1361
|
-
});
|
|
1360
|
+
addEventListener(node, eventName, syncToModel);
|
|
1361
|
+
if (!lazy && shouldCast && eventName !== "change") {
|
|
1362
|
+
addEventListener(node, "change", () => write(node, cast(read(node))));
|
|
1362
1363
|
}
|
|
1363
|
-
if (
|
|
1364
|
+
if (ime && !lazy) {
|
|
1364
1365
|
addEventListener(node, "compositionstart", () => {
|
|
1365
1366
|
composing = true;
|
|
1366
1367
|
});
|
|
1367
1368
|
addEventListener(node, "compositionend", () => {
|
|
1368
1369
|
if (!composing) return;
|
|
1369
1370
|
composing = false;
|
|
1370
|
-
|
|
1371
|
+
syncToModel();
|
|
1371
1372
|
});
|
|
1372
1373
|
}
|
|
1373
1374
|
const runner = signals.effect(() => {
|
|
1374
|
-
const value =
|
|
1375
|
-
if (
|
|
1375
|
+
const value = getModel();
|
|
1376
|
+
if (ime && !lazy && isFocused(node)) {
|
|
1376
1377
|
if (composing) return;
|
|
1377
|
-
|
|
1378
|
-
if (Object.is(current, value)) return;
|
|
1378
|
+
if (Object.is(cast(read(node)), value)) return;
|
|
1379
1379
|
}
|
|
1380
|
-
|
|
1380
|
+
write(node, value);
|
|
1381
1381
|
});
|
|
1382
1382
|
if (getActiveScope()) {
|
|
1383
1383
|
onCleanup(() => runner.stop());
|
|
@@ -1451,10 +1451,10 @@ function Portal(props) {
|
|
|
1451
1451
|
placeholder[PORTAL_COMPONENT] = true;
|
|
1452
1452
|
const { children } = props;
|
|
1453
1453
|
if (children == null) return placeholder;
|
|
1454
|
-
const
|
|
1454
|
+
const parentScope = getActiveScope();
|
|
1455
1455
|
let innerScope = null;
|
|
1456
1456
|
const mountAt = (parent, before) => {
|
|
1457
|
-
innerScope = createScope(
|
|
1457
|
+
innerScope = createScope(parentScope);
|
|
1458
1458
|
runWithScope(innerScope, () => {
|
|
1459
1459
|
insert(parent, () => children, before);
|
|
1460
1460
|
});
|