what-core 0.8.1 → 0.8.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/compiler.js +1799 -0
- package/dist/compiler.js.map +7 -0
- package/dist/compiler.min.js +2 -0
- package/dist/compiler.min.js.map +7 -0
- package/dist/devtools.js +10 -0
- package/dist/devtools.js.map +7 -0
- package/dist/devtools.min.js +2 -0
- package/dist/devtools.min.js.map +7 -0
- package/package.json +1 -1
package/dist/compiler.js
ADDED
|
@@ -0,0 +1,1799 @@
|
|
|
1
|
+
// packages/core/src/reactive.js
|
|
2
|
+
var __DEV__ = typeof process !== "undefined" ? true : true;
|
|
3
|
+
var __devtools = null;
|
|
4
|
+
var currentEffect = null;
|
|
5
|
+
var currentRoot = null;
|
|
6
|
+
var currentOwner = null;
|
|
7
|
+
var insideComputed = false;
|
|
8
|
+
var batchDepth = 0;
|
|
9
|
+
var pendingEffects = [];
|
|
10
|
+
var pendingNeedSort = false;
|
|
11
|
+
var subSetOwner = /* @__PURE__ */ new WeakMap();
|
|
12
|
+
var NEEDS_UPSTREAM = /* @__PURE__ */ Symbol("needs_upstream");
|
|
13
|
+
function signal(initial, debugName) {
|
|
14
|
+
let value = initial;
|
|
15
|
+
const subs = /* @__PURE__ */ new Set();
|
|
16
|
+
function sig(...args) {
|
|
17
|
+
if (args.length === 0) {
|
|
18
|
+
if (currentEffect) {
|
|
19
|
+
subs.add(currentEffect);
|
|
20
|
+
currentEffect.deps.push(subs);
|
|
21
|
+
}
|
|
22
|
+
return value;
|
|
23
|
+
}
|
|
24
|
+
if (__DEV__ && insideComputed) {
|
|
25
|
+
console.warn(
|
|
26
|
+
"[what] Signal.set() called inside a computed function. This may cause infinite loops. Use effect() instead." + (debugName ? ` (signal: ${debugName})` : "")
|
|
27
|
+
);
|
|
28
|
+
}
|
|
29
|
+
const nextVal = typeof args[0] === "function" ? args[0](value) : args[0];
|
|
30
|
+
if (Object.is(value, nextVal)) return;
|
|
31
|
+
value = nextVal;
|
|
32
|
+
if (__DEV__ && __devtools) __devtools.onSignalUpdate(sig);
|
|
33
|
+
if (subs.size > 0) notify(subs);
|
|
34
|
+
}
|
|
35
|
+
sig.set = (next) => {
|
|
36
|
+
if (__DEV__ && insideComputed) {
|
|
37
|
+
console.warn(
|
|
38
|
+
"[what] Signal.set() called inside a computed function. This may cause infinite loops. Use effect() instead." + (debugName ? ` (signal: ${debugName})` : "")
|
|
39
|
+
);
|
|
40
|
+
}
|
|
41
|
+
const nextVal = typeof next === "function" ? next(value) : next;
|
|
42
|
+
if (Object.is(value, nextVal)) return;
|
|
43
|
+
value = nextVal;
|
|
44
|
+
if (__DEV__ && __devtools) __devtools.onSignalUpdate(sig);
|
|
45
|
+
if (subs.size > 0) notify(subs);
|
|
46
|
+
};
|
|
47
|
+
sig.peek = () => value;
|
|
48
|
+
sig.subscribe = (fn) => {
|
|
49
|
+
return effect(() => fn(sig()));
|
|
50
|
+
};
|
|
51
|
+
sig._signal = true;
|
|
52
|
+
if (__DEV__) {
|
|
53
|
+
sig._subs = subs;
|
|
54
|
+
if (debugName) sig._debugName = debugName;
|
|
55
|
+
}
|
|
56
|
+
if (__DEV__ && __devtools) __devtools.onSignalCreate(sig);
|
|
57
|
+
return sig;
|
|
58
|
+
}
|
|
59
|
+
function _updateLevel(e) {
|
|
60
|
+
let maxDepLevel = 0;
|
|
61
|
+
const deps = e.deps;
|
|
62
|
+
for (let i = 0; i < deps.length; i++) {
|
|
63
|
+
const owner = subSetOwner.get(deps[i]);
|
|
64
|
+
if (owner) {
|
|
65
|
+
const depLevel = owner._level;
|
|
66
|
+
if (depLevel > maxDepLevel) maxDepLevel = depLevel;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
e._level = maxDepLevel + 1;
|
|
70
|
+
}
|
|
71
|
+
function effect(fn, opts) {
|
|
72
|
+
const e = _createEffect(fn);
|
|
73
|
+
e._level = 1;
|
|
74
|
+
const prev = currentEffect;
|
|
75
|
+
currentEffect = e;
|
|
76
|
+
try {
|
|
77
|
+
const result = e.fn();
|
|
78
|
+
if (typeof result === "function") e._cleanup = result;
|
|
79
|
+
} finally {
|
|
80
|
+
currentEffect = prev;
|
|
81
|
+
}
|
|
82
|
+
_updateLevel(e);
|
|
83
|
+
if (opts?.stable) e._stable = true;
|
|
84
|
+
const dispose = () => _disposeEffect(e);
|
|
85
|
+
if (currentRoot) {
|
|
86
|
+
currentRoot.disposals.push(dispose);
|
|
87
|
+
}
|
|
88
|
+
return dispose;
|
|
89
|
+
}
|
|
90
|
+
function _createEffect(fn, lazy) {
|
|
91
|
+
const e = {
|
|
92
|
+
fn,
|
|
93
|
+
deps: [],
|
|
94
|
+
// array of subscriber sets (cheaper than Set for typical 1-3 deps)
|
|
95
|
+
lazy: lazy || false,
|
|
96
|
+
_onNotify: null,
|
|
97
|
+
disposed: false,
|
|
98
|
+
_pending: false,
|
|
99
|
+
_stable: false,
|
|
100
|
+
// stable effects skip cleanup/re-subscribe on re-run
|
|
101
|
+
_level: 0,
|
|
102
|
+
// topological depth: signals=0, computed/effects=max(deps)+1
|
|
103
|
+
_computed: false,
|
|
104
|
+
// true for computed inner effects
|
|
105
|
+
_computedSubs: null,
|
|
106
|
+
// reference to the computed's subscriber set
|
|
107
|
+
_isDirty: null,
|
|
108
|
+
// function to check if computed is dirty (set by computed())
|
|
109
|
+
_markDirty: null
|
|
110
|
+
// function to mark computed dirty (set by computed())
|
|
111
|
+
};
|
|
112
|
+
if (__DEV__ && __devtools) __devtools.onEffectCreate(e);
|
|
113
|
+
return e;
|
|
114
|
+
}
|
|
115
|
+
function _runEffect(e) {
|
|
116
|
+
if (e.disposed) return;
|
|
117
|
+
if (e._stable) {
|
|
118
|
+
runStableEffect(e);
|
|
119
|
+
return;
|
|
120
|
+
}
|
|
121
|
+
cleanup(e);
|
|
122
|
+
runEffectCleanup(e, "effect cleanup");
|
|
123
|
+
const prev = currentEffect;
|
|
124
|
+
currentEffect = e;
|
|
125
|
+
try {
|
|
126
|
+
const result = e.fn();
|
|
127
|
+
if (typeof result === "function") {
|
|
128
|
+
e._cleanup = result;
|
|
129
|
+
}
|
|
130
|
+
} catch (err) {
|
|
131
|
+
if (err === NEEDS_UPSTREAM) throw err;
|
|
132
|
+
if (__devtools?.onError) __devtools.onError(err, { type: "effect", effect: e });
|
|
133
|
+
throw err;
|
|
134
|
+
} finally {
|
|
135
|
+
currentEffect = prev;
|
|
136
|
+
}
|
|
137
|
+
if (__DEV__ && __devtools?.onEffectRun) __devtools.onEffectRun(e);
|
|
138
|
+
}
|
|
139
|
+
function _disposeEffect(e) {
|
|
140
|
+
e.disposed = true;
|
|
141
|
+
if (__DEV__ && __devtools) __devtools.onEffectDispose(e);
|
|
142
|
+
cleanup(e);
|
|
143
|
+
runEffectCleanup(e, "effect cleanup on dispose");
|
|
144
|
+
}
|
|
145
|
+
function reportEffectCleanupError(err, e, phase) {
|
|
146
|
+
if (__devtools?.onError) __devtools.onError(err, { type: "effect-cleanup", effect: e, phase });
|
|
147
|
+
if (__DEV__) console.warn(`[what] Error in ${phase}:`, err);
|
|
148
|
+
}
|
|
149
|
+
function runEffectCleanup(e, phase) {
|
|
150
|
+
if (!e._cleanup) return;
|
|
151
|
+
const cleanupFn = e._cleanup;
|
|
152
|
+
e._cleanup = null;
|
|
153
|
+
try {
|
|
154
|
+
cleanupFn();
|
|
155
|
+
} catch (err) {
|
|
156
|
+
reportEffectCleanupError(err, e, phase);
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
function runStableEffect(e) {
|
|
160
|
+
const prev = currentEffect;
|
|
161
|
+
currentEffect = null;
|
|
162
|
+
try {
|
|
163
|
+
runEffectCleanup(e, "stable effect cleanup");
|
|
164
|
+
const result = e.fn();
|
|
165
|
+
if (typeof result === "function") e._cleanup = result;
|
|
166
|
+
} catch (err) {
|
|
167
|
+
if (__devtools?.onError) __devtools.onError(err, { type: "effect", effect: e });
|
|
168
|
+
if (__DEV__) console.warn("[what] Error in stable effect:", err);
|
|
169
|
+
} finally {
|
|
170
|
+
currentEffect = prev;
|
|
171
|
+
}
|
|
172
|
+
if (__DEV__ && __devtools?.onEffectRun) __devtools.onEffectRun(e);
|
|
173
|
+
}
|
|
174
|
+
function cleanup(e) {
|
|
175
|
+
const deps = e.deps;
|
|
176
|
+
for (let i = 0; i < deps.length; i++) deps[i].delete(e);
|
|
177
|
+
deps.length = 0;
|
|
178
|
+
}
|
|
179
|
+
var notifyDepth = 0;
|
|
180
|
+
var notifyQueue = null;
|
|
181
|
+
var notifyQueueLen = 0;
|
|
182
|
+
function notify(subs) {
|
|
183
|
+
if (notifyDepth === 0) {
|
|
184
|
+
notifyDepth = 1;
|
|
185
|
+
try {
|
|
186
|
+
for (const e of subs) {
|
|
187
|
+
if (e.disposed) continue;
|
|
188
|
+
if (e._onNotify) {
|
|
189
|
+
e._onNotify();
|
|
190
|
+
} else if (batchDepth === 0 && e._stable) {
|
|
191
|
+
runStableEffect(e);
|
|
192
|
+
} else if (!e._pending) {
|
|
193
|
+
e._pending = true;
|
|
194
|
+
const level = e._level;
|
|
195
|
+
const len = pendingEffects.length;
|
|
196
|
+
if (len > 0 && pendingEffects[len - 1]._level > level) {
|
|
197
|
+
pendingNeedSort = true;
|
|
198
|
+
}
|
|
199
|
+
pendingEffects.push(e);
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
if (notifyQueueLen > 0) {
|
|
203
|
+
let qi = 0;
|
|
204
|
+
while (qi < notifyQueueLen) {
|
|
205
|
+
const queuedSubs = notifyQueue[qi];
|
|
206
|
+
notifyQueue[qi] = null;
|
|
207
|
+
qi++;
|
|
208
|
+
for (const e of queuedSubs) {
|
|
209
|
+
if (e.disposed) continue;
|
|
210
|
+
if (e._onNotify) {
|
|
211
|
+
e._onNotify();
|
|
212
|
+
} else if (batchDepth === 0 && e._stable) {
|
|
213
|
+
runStableEffect(e);
|
|
214
|
+
} else if (!e._pending) {
|
|
215
|
+
e._pending = true;
|
|
216
|
+
const level = e._level;
|
|
217
|
+
const len = pendingEffects.length;
|
|
218
|
+
if (len > 0 && pendingEffects[len - 1]._level > level) {
|
|
219
|
+
pendingNeedSort = true;
|
|
220
|
+
}
|
|
221
|
+
pendingEffects.push(e);
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
notifyQueueLen = 0;
|
|
226
|
+
}
|
|
227
|
+
} finally {
|
|
228
|
+
notifyDepth = 0;
|
|
229
|
+
}
|
|
230
|
+
if (batchDepth === 0 && pendingEffects.length > 0) scheduleMicrotask();
|
|
231
|
+
} else {
|
|
232
|
+
if (notifyQueue === null) notifyQueue = [];
|
|
233
|
+
if (notifyQueueLen >= notifyQueue.length) {
|
|
234
|
+
notifyQueue.push(subs);
|
|
235
|
+
} else {
|
|
236
|
+
notifyQueue[notifyQueueLen] = subs;
|
|
237
|
+
}
|
|
238
|
+
notifyQueueLen++;
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
var microtaskScheduled = false;
|
|
242
|
+
function scheduleMicrotask() {
|
|
243
|
+
if (!microtaskScheduled) {
|
|
244
|
+
microtaskScheduled = true;
|
|
245
|
+
queueMicrotask(() => {
|
|
246
|
+
microtaskScheduled = false;
|
|
247
|
+
flush();
|
|
248
|
+
});
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
var isFlushing = false;
|
|
252
|
+
function flush() {
|
|
253
|
+
if (isFlushing) return;
|
|
254
|
+
isFlushing = true;
|
|
255
|
+
try {
|
|
256
|
+
let iterations = 0;
|
|
257
|
+
while (pendingEffects.length > 0 && iterations < 25) {
|
|
258
|
+
const batch2 = pendingEffects;
|
|
259
|
+
pendingEffects = [];
|
|
260
|
+
if (batch2.length > 1 && pendingNeedSort) {
|
|
261
|
+
batch2.sort((a, b) => a._level - b._level);
|
|
262
|
+
}
|
|
263
|
+
pendingNeedSort = false;
|
|
264
|
+
for (let i = 0; i < batch2.length; i++) {
|
|
265
|
+
const e = batch2[i];
|
|
266
|
+
e._pending = false;
|
|
267
|
+
if (!e.disposed && !e._onNotify) {
|
|
268
|
+
const prevDepsLen = e.deps.length;
|
|
269
|
+
_runEffect(e);
|
|
270
|
+
if (!e._computed && e.deps.length !== prevDepsLen) {
|
|
271
|
+
_updateLevel(e);
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
iterations++;
|
|
276
|
+
}
|
|
277
|
+
if (iterations >= 25) {
|
|
278
|
+
for (let i = 0; i < pendingEffects.length; i++) pendingEffects[i]._pending = false;
|
|
279
|
+
pendingEffects.length = 0;
|
|
280
|
+
if (__DEV__) {
|
|
281
|
+
const remaining = pendingEffects.slice(0, 3);
|
|
282
|
+
const effectNames = remaining.map((e) => e.fn?.name || e.fn?.toString().slice(0, 60) || "(anonymous)");
|
|
283
|
+
console.warn(
|
|
284
|
+
`[what] Possible infinite effect loop detected (25 iterations). Likely cause: an effect writes to a signal it also reads, creating a cycle. Use untrack() to read signals without subscribing. Looping effects: ${effectNames.join(", ")}`
|
|
285
|
+
);
|
|
286
|
+
} else {
|
|
287
|
+
console.warn("[what] Possible infinite effect loop detected");
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
} finally {
|
|
291
|
+
isFlushing = false;
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
function untrack(fn) {
|
|
295
|
+
const prev = currentEffect;
|
|
296
|
+
currentEffect = null;
|
|
297
|
+
try {
|
|
298
|
+
return fn();
|
|
299
|
+
} finally {
|
|
300
|
+
currentEffect = prev;
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
function createRoot(fn) {
|
|
304
|
+
const prevRoot = currentRoot;
|
|
305
|
+
const prevOwner = currentOwner;
|
|
306
|
+
const root = {
|
|
307
|
+
disposals: [],
|
|
308
|
+
owner: currentOwner,
|
|
309
|
+
// parent owner for ownership tree
|
|
310
|
+
children: [],
|
|
311
|
+
// child roots (ownership tree)
|
|
312
|
+
_disposed: false
|
|
313
|
+
};
|
|
314
|
+
if (currentOwner) {
|
|
315
|
+
currentOwner.children.push(root);
|
|
316
|
+
}
|
|
317
|
+
currentRoot = root;
|
|
318
|
+
currentOwner = root;
|
|
319
|
+
try {
|
|
320
|
+
const dispose = () => {
|
|
321
|
+
if (root._disposed) return;
|
|
322
|
+
root._disposed = true;
|
|
323
|
+
for (let i = root.children.length - 1; i >= 0; i--) {
|
|
324
|
+
_disposeRoot(root.children[i]);
|
|
325
|
+
}
|
|
326
|
+
root.children.length = 0;
|
|
327
|
+
for (let i = root.disposals.length - 1; i >= 0; i--) {
|
|
328
|
+
root.disposals[i]();
|
|
329
|
+
}
|
|
330
|
+
root.disposals.length = 0;
|
|
331
|
+
if (root.owner) {
|
|
332
|
+
const idx = root.owner.children.indexOf(root);
|
|
333
|
+
if (idx >= 0) root.owner.children.splice(idx, 1);
|
|
334
|
+
}
|
|
335
|
+
};
|
|
336
|
+
return fn(dispose);
|
|
337
|
+
} finally {
|
|
338
|
+
currentRoot = prevRoot;
|
|
339
|
+
currentOwner = prevOwner;
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
function _disposeRoot(root) {
|
|
343
|
+
if (root._disposed) return;
|
|
344
|
+
root._disposed = true;
|
|
345
|
+
for (let i = root.children.length - 1; i >= 0; i--) {
|
|
346
|
+
_disposeRoot(root.children[i]);
|
|
347
|
+
}
|
|
348
|
+
root.children.length = 0;
|
|
349
|
+
for (let i = root.disposals.length - 1; i >= 0; i--) {
|
|
350
|
+
root.disposals[i]();
|
|
351
|
+
}
|
|
352
|
+
root.disposals.length = 0;
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
// packages/core/src/components.js
|
|
356
|
+
var _getCurrentComponent = null;
|
|
357
|
+
function _injectGetCurrentComponent(fn) {
|
|
358
|
+
_getCurrentComponent = fn;
|
|
359
|
+
}
|
|
360
|
+
function reportError(error, startCtx) {
|
|
361
|
+
let ctx = startCtx || _getCurrentComponent?.();
|
|
362
|
+
while (ctx) {
|
|
363
|
+
if (ctx._errorBoundary) {
|
|
364
|
+
ctx._errorBoundary(error);
|
|
365
|
+
return true;
|
|
366
|
+
}
|
|
367
|
+
ctx = ctx._parentCtx;
|
|
368
|
+
}
|
|
369
|
+
return false;
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
// packages/core/src/helpers.js
|
|
373
|
+
var _getCurrentComponentRef = null;
|
|
374
|
+
function _setComponentRef(fn) {
|
|
375
|
+
_getCurrentComponentRef = fn;
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
// packages/core/src/security.js
|
|
379
|
+
var URL_ATTRS = /* @__PURE__ */ new Set([
|
|
380
|
+
"href",
|
|
381
|
+
"src",
|
|
382
|
+
"action",
|
|
383
|
+
"formaction",
|
|
384
|
+
"poster",
|
|
385
|
+
"cite",
|
|
386
|
+
"background",
|
|
387
|
+
"xlink:href"
|
|
388
|
+
]);
|
|
389
|
+
var URL_LIST_ATTRS = /* @__PURE__ */ new Set(["srcset"]);
|
|
390
|
+
function normalizeAttrName(name) {
|
|
391
|
+
return String(name).toLowerCase();
|
|
392
|
+
}
|
|
393
|
+
function normalizeUrlForProtocolCheck(url) {
|
|
394
|
+
return String(url).trim().replace(/[\s\x00-\x1f\x7f]/g, "").toLowerCase();
|
|
395
|
+
}
|
|
396
|
+
function isSafeUrlValue(value) {
|
|
397
|
+
if (typeof value !== "string") return true;
|
|
398
|
+
const normalized = normalizeUrlForProtocolCheck(value);
|
|
399
|
+
return !(normalized.startsWith("javascript:") || normalized.startsWith("data:") || normalized.startsWith("vbscript:"));
|
|
400
|
+
}
|
|
401
|
+
function isSafeSrcsetValue(value) {
|
|
402
|
+
if (typeof value !== "string") return true;
|
|
403
|
+
return value.split(",").every((candidate) => {
|
|
404
|
+
const url = candidate.trim().split(/\s+/, 1)[0] || "";
|
|
405
|
+
return url === "" || isSafeUrlValue(url);
|
|
406
|
+
});
|
|
407
|
+
}
|
|
408
|
+
function isUrlAttribute(name) {
|
|
409
|
+
return URL_ATTRS.has(normalizeAttrName(name));
|
|
410
|
+
}
|
|
411
|
+
function isUrlListAttribute(name) {
|
|
412
|
+
return URL_LIST_ATTRS.has(normalizeAttrName(name));
|
|
413
|
+
}
|
|
414
|
+
function isSafeUrlAttributeValue(name, value) {
|
|
415
|
+
if (isUrlListAttribute(name)) return isSafeSrcsetValue(value);
|
|
416
|
+
if (isUrlAttribute(name)) return isSafeUrlValue(value);
|
|
417
|
+
return true;
|
|
418
|
+
}
|
|
419
|
+
function getDomAttributeName(name) {
|
|
420
|
+
if (name === "className") return "class";
|
|
421
|
+
if (name === "htmlFor") return "for";
|
|
422
|
+
return normalizeAttrName(name) === "formaction" ? "formaction" : name;
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
// packages/core/src/dom.js
|
|
426
|
+
var SVG_ELEMENTS = /* @__PURE__ */ new Set([
|
|
427
|
+
"svg",
|
|
428
|
+
"path",
|
|
429
|
+
"circle",
|
|
430
|
+
"rect",
|
|
431
|
+
"line",
|
|
432
|
+
"polyline",
|
|
433
|
+
"polygon",
|
|
434
|
+
"ellipse",
|
|
435
|
+
"g",
|
|
436
|
+
"defs",
|
|
437
|
+
"use",
|
|
438
|
+
"symbol",
|
|
439
|
+
"clipPath",
|
|
440
|
+
"mask",
|
|
441
|
+
"pattern",
|
|
442
|
+
"image",
|
|
443
|
+
"text",
|
|
444
|
+
"tspan",
|
|
445
|
+
"textPath",
|
|
446
|
+
"foreignObject",
|
|
447
|
+
"linearGradient",
|
|
448
|
+
"radialGradient",
|
|
449
|
+
"stop",
|
|
450
|
+
"marker",
|
|
451
|
+
"animate",
|
|
452
|
+
"animateTransform",
|
|
453
|
+
"animateMotion",
|
|
454
|
+
"set",
|
|
455
|
+
"filter",
|
|
456
|
+
"feBlend",
|
|
457
|
+
"feColorMatrix",
|
|
458
|
+
"feComponentTransfer",
|
|
459
|
+
"feComposite",
|
|
460
|
+
"feConvolveMatrix",
|
|
461
|
+
"feDiffuseLighting",
|
|
462
|
+
"feDisplacementMap",
|
|
463
|
+
"feFlood",
|
|
464
|
+
"feGaussianBlur",
|
|
465
|
+
"feImage",
|
|
466
|
+
"feMerge",
|
|
467
|
+
"feMergeNode",
|
|
468
|
+
"feMorphology",
|
|
469
|
+
"feOffset",
|
|
470
|
+
"feSpecularLighting",
|
|
471
|
+
"feTile",
|
|
472
|
+
"feTurbulence"
|
|
473
|
+
]);
|
|
474
|
+
var SVG_NS = "http://www.w3.org/2000/svg";
|
|
475
|
+
var mountedComponents = /* @__PURE__ */ new Set();
|
|
476
|
+
var _commentCtxMap = /* @__PURE__ */ new WeakMap();
|
|
477
|
+
function isDomNode(value) {
|
|
478
|
+
if (!value || typeof value !== "object") return false;
|
|
479
|
+
if (typeof Node !== "undefined" && value instanceof Node) return true;
|
|
480
|
+
return typeof value.nodeType === "number" && typeof value.nodeName === "string";
|
|
481
|
+
}
|
|
482
|
+
function isVNode(value) {
|
|
483
|
+
return !!value && typeof value === "object" && (value._vnode === true || "tag" in value);
|
|
484
|
+
}
|
|
485
|
+
function disposeComponent(ctx) {
|
|
486
|
+
if (ctx.disposed) return;
|
|
487
|
+
ctx.disposed = true;
|
|
488
|
+
if (ctx.cleanups) {
|
|
489
|
+
for (const cleanup2 of ctx.cleanups) {
|
|
490
|
+
try {
|
|
491
|
+
cleanup2();
|
|
492
|
+
} catch (e) {
|
|
493
|
+
console.error("[what] cleanup error:", e);
|
|
494
|
+
}
|
|
495
|
+
}
|
|
496
|
+
}
|
|
497
|
+
if (ctx.effects) {
|
|
498
|
+
for (const dispose of ctx.effects) {
|
|
499
|
+
try {
|
|
500
|
+
dispose();
|
|
501
|
+
} catch (e) {
|
|
502
|
+
}
|
|
503
|
+
}
|
|
504
|
+
}
|
|
505
|
+
if (ctx.hooks) {
|
|
506
|
+
for (const hook of ctx.hooks) {
|
|
507
|
+
if (hook && typeof hook.cleanup === "function") {
|
|
508
|
+
try {
|
|
509
|
+
hook.cleanup();
|
|
510
|
+
} catch (e) {
|
|
511
|
+
console.error("[what] hook cleanup error:", e);
|
|
512
|
+
}
|
|
513
|
+
}
|
|
514
|
+
}
|
|
515
|
+
}
|
|
516
|
+
if (ctx._cleanupCallbacks) {
|
|
517
|
+
for (const fn of ctx._cleanupCallbacks) {
|
|
518
|
+
try {
|
|
519
|
+
fn();
|
|
520
|
+
} catch (e) {
|
|
521
|
+
console.error("[what] onCleanup error:", e);
|
|
522
|
+
}
|
|
523
|
+
}
|
|
524
|
+
}
|
|
525
|
+
if (__DEV__ && __devtools?.onComponentUnmount) __devtools.onComponentUnmount(ctx);
|
|
526
|
+
mountedComponents.delete(ctx);
|
|
527
|
+
}
|
|
528
|
+
function disposeTree(node) {
|
|
529
|
+
if (!node) return;
|
|
530
|
+
if (node._componentCtx) {
|
|
531
|
+
disposeComponent(node._componentCtx);
|
|
532
|
+
}
|
|
533
|
+
const commentCtx = _commentCtxMap.get(node);
|
|
534
|
+
if (commentCtx) {
|
|
535
|
+
disposeComponent(commentCtx);
|
|
536
|
+
}
|
|
537
|
+
if (node._dispose) {
|
|
538
|
+
try {
|
|
539
|
+
node._dispose();
|
|
540
|
+
} catch (e) {
|
|
541
|
+
}
|
|
542
|
+
}
|
|
543
|
+
if (node._propEffects) {
|
|
544
|
+
for (const key in node._propEffects) {
|
|
545
|
+
try {
|
|
546
|
+
node._propEffects[key]();
|
|
547
|
+
} catch (e) {
|
|
548
|
+
}
|
|
549
|
+
}
|
|
550
|
+
}
|
|
551
|
+
if (node.childNodes) {
|
|
552
|
+
for (const child of node.childNodes) {
|
|
553
|
+
disposeTree(child);
|
|
554
|
+
}
|
|
555
|
+
}
|
|
556
|
+
}
|
|
557
|
+
function createDOM(vnode, parent, isSvg) {
|
|
558
|
+
if (vnode == null || vnode === false || vnode === true) {
|
|
559
|
+
return document.createComment("");
|
|
560
|
+
}
|
|
561
|
+
if (typeof vnode === "string" || typeof vnode === "number") {
|
|
562
|
+
return document.createTextNode(String(vnode));
|
|
563
|
+
}
|
|
564
|
+
if (isDomNode(vnode)) {
|
|
565
|
+
return vnode;
|
|
566
|
+
}
|
|
567
|
+
if (typeof vnode === "function") {
|
|
568
|
+
const startMarker = document.createComment("fn");
|
|
569
|
+
const endMarker = document.createComment("/fn");
|
|
570
|
+
let currentNodes = [];
|
|
571
|
+
const frag = document.createDocumentFragment();
|
|
572
|
+
frag.appendChild(startMarker);
|
|
573
|
+
frag.appendChild(endMarker);
|
|
574
|
+
const dispose = effect(() => {
|
|
575
|
+
const val = vnode();
|
|
576
|
+
const vnodes = val == null || val === false || val === true ? [] : Array.isArray(val) ? val : [val];
|
|
577
|
+
const realParent = endMarker.parentNode;
|
|
578
|
+
if (!realParent) return;
|
|
579
|
+
for (const old of currentNodes) {
|
|
580
|
+
disposeTree(old);
|
|
581
|
+
if (old.parentNode === realParent) realParent.removeChild(old);
|
|
582
|
+
}
|
|
583
|
+
currentNodes = [];
|
|
584
|
+
for (const v of vnodes) {
|
|
585
|
+
const node = createDOM(v, realParent, parent?._isSvg);
|
|
586
|
+
if (node) {
|
|
587
|
+
if (node.nodeType === 11) {
|
|
588
|
+
const children = Array.from(node.childNodes);
|
|
589
|
+
realParent.insertBefore(node, endMarker);
|
|
590
|
+
for (const child of children) currentNodes.push(child);
|
|
591
|
+
} else {
|
|
592
|
+
realParent.insertBefore(node, endMarker);
|
|
593
|
+
currentNodes.push(node);
|
|
594
|
+
}
|
|
595
|
+
}
|
|
596
|
+
}
|
|
597
|
+
});
|
|
598
|
+
startMarker._dispose = dispose;
|
|
599
|
+
endMarker._dispose = dispose;
|
|
600
|
+
return frag;
|
|
601
|
+
}
|
|
602
|
+
if (Array.isArray(vnode)) {
|
|
603
|
+
const frag = document.createDocumentFragment();
|
|
604
|
+
for (const child of vnode) {
|
|
605
|
+
const node = createDOM(child, parent, isSvg);
|
|
606
|
+
if (node) frag.appendChild(node);
|
|
607
|
+
}
|
|
608
|
+
return frag;
|
|
609
|
+
}
|
|
610
|
+
if (isVNode(vnode) && typeof vnode.tag === "function") {
|
|
611
|
+
return createComponent(vnode, parent, isSvg);
|
|
612
|
+
}
|
|
613
|
+
if (isVNode(vnode) && (vnode.tag === "__errorBoundary" || vnode.tag === "__suspense" || vnode.tag === "__portal")) {
|
|
614
|
+
return createComponent(vnode, parent, isSvg);
|
|
615
|
+
}
|
|
616
|
+
if (isVNode(vnode)) {
|
|
617
|
+
return createElementFromVNode(vnode, parent, isSvg);
|
|
618
|
+
}
|
|
619
|
+
return document.createTextNode(String(vnode));
|
|
620
|
+
}
|
|
621
|
+
var componentStack = [];
|
|
622
|
+
function getCurrentComponent() {
|
|
623
|
+
return componentStack[componentStack.length - 1];
|
|
624
|
+
}
|
|
625
|
+
_injectGetCurrentComponent(getCurrentComponent);
|
|
626
|
+
_setComponentRef(getCurrentComponent);
|
|
627
|
+
function createComponent(vnode, parent, isSvg) {
|
|
628
|
+
let { tag: Component, props, children } = vnode;
|
|
629
|
+
if (typeof Component === "function" && (Component.prototype?.isReactComponent || Component.prototype?.render)) {
|
|
630
|
+
const ClassComp = Component;
|
|
631
|
+
Component = function ClassComponentBridge(props2) {
|
|
632
|
+
const instance = new ClassComp(props2);
|
|
633
|
+
return instance.render();
|
|
634
|
+
};
|
|
635
|
+
Component.displayName = ClassComp.displayName || ClassComp.name || "ClassComponent";
|
|
636
|
+
}
|
|
637
|
+
if (Component === "__errorBoundary" || vnode.tag === "__errorBoundary") {
|
|
638
|
+
return createErrorBoundary(vnode, parent);
|
|
639
|
+
}
|
|
640
|
+
if (Component === "__suspense" || vnode.tag === "__suspense") {
|
|
641
|
+
return createSuspenseBoundary(vnode, parent);
|
|
642
|
+
}
|
|
643
|
+
if (Component === "__portal" || vnode.tag === "__portal") {
|
|
644
|
+
return createPortalDOM(vnode, parent);
|
|
645
|
+
}
|
|
646
|
+
const ctx = {
|
|
647
|
+
hooks: [],
|
|
648
|
+
hookIndex: 0,
|
|
649
|
+
effects: [],
|
|
650
|
+
cleanups: [],
|
|
651
|
+
mounted: false,
|
|
652
|
+
disposed: false,
|
|
653
|
+
Component,
|
|
654
|
+
_parentCtx: componentStack[componentStack.length - 1] || null,
|
|
655
|
+
_errorBoundary: (() => {
|
|
656
|
+
let p = componentStack[componentStack.length - 1];
|
|
657
|
+
while (p) {
|
|
658
|
+
if (p._errorBoundary) return p._errorBoundary;
|
|
659
|
+
p = p._parentCtx;
|
|
660
|
+
}
|
|
661
|
+
return null;
|
|
662
|
+
})()
|
|
663
|
+
};
|
|
664
|
+
const startComment = document.createComment("c:start");
|
|
665
|
+
const endComment = document.createComment("c:end");
|
|
666
|
+
_commentCtxMap.set(startComment, ctx);
|
|
667
|
+
ctx._startComment = startComment;
|
|
668
|
+
ctx._endComment = endComment;
|
|
669
|
+
const container = document.createDocumentFragment();
|
|
670
|
+
container._componentCtx = ctx;
|
|
671
|
+
ctx._wrapper = startComment;
|
|
672
|
+
mountedComponents.add(ctx);
|
|
673
|
+
if (__DEV__ && __devtools?.onComponentMount) __devtools.onComponentMount(ctx);
|
|
674
|
+
const propsChildren = children.length === 0 ? void 0 : children.length === 1 ? children[0] : children;
|
|
675
|
+
const propsSignal = signal({ ...props, children: propsChildren });
|
|
676
|
+
ctx._propsSignal = propsSignal;
|
|
677
|
+
const reactiveProps = new Proxy({}, {
|
|
678
|
+
get(_, key) {
|
|
679
|
+
const current = propsSignal();
|
|
680
|
+
return current[key];
|
|
681
|
+
},
|
|
682
|
+
has(_, key) {
|
|
683
|
+
const current = propsSignal();
|
|
684
|
+
return key in current;
|
|
685
|
+
},
|
|
686
|
+
ownKeys() {
|
|
687
|
+
const current = propsSignal();
|
|
688
|
+
return Reflect.ownKeys(current);
|
|
689
|
+
},
|
|
690
|
+
getOwnPropertyDescriptor(_, key) {
|
|
691
|
+
const current = propsSignal();
|
|
692
|
+
if (key in current) {
|
|
693
|
+
return { value: current[key], writable: false, enumerable: true, configurable: true };
|
|
694
|
+
}
|
|
695
|
+
return void 0;
|
|
696
|
+
}
|
|
697
|
+
});
|
|
698
|
+
componentStack.push(ctx);
|
|
699
|
+
let result;
|
|
700
|
+
try {
|
|
701
|
+
result = Component(reactiveProps);
|
|
702
|
+
} catch (error) {
|
|
703
|
+
componentStack.pop();
|
|
704
|
+
if (!reportError(error, ctx)) {
|
|
705
|
+
console.error("[what] Uncaught error in component:", Component.name || "Anonymous", error);
|
|
706
|
+
throw error;
|
|
707
|
+
}
|
|
708
|
+
container.appendChild(startComment);
|
|
709
|
+
container.appendChild(endComment);
|
|
710
|
+
return container;
|
|
711
|
+
}
|
|
712
|
+
componentStack.pop();
|
|
713
|
+
ctx.mounted = true;
|
|
714
|
+
if (ctx._mountCallbacks) {
|
|
715
|
+
queueMicrotask(() => {
|
|
716
|
+
if (ctx.disposed) return;
|
|
717
|
+
for (const fn of ctx._mountCallbacks) {
|
|
718
|
+
try {
|
|
719
|
+
fn();
|
|
720
|
+
} catch (e) {
|
|
721
|
+
console.error("[what] onMount error:", e);
|
|
722
|
+
}
|
|
723
|
+
}
|
|
724
|
+
});
|
|
725
|
+
}
|
|
726
|
+
container.appendChild(startComment);
|
|
727
|
+
const vnodes = Array.isArray(result) ? result : [result];
|
|
728
|
+
for (const v of vnodes) {
|
|
729
|
+
const node = createDOM(v, container, isSvg);
|
|
730
|
+
if (node) container.appendChild(node);
|
|
731
|
+
}
|
|
732
|
+
container.appendChild(endComment);
|
|
733
|
+
return container;
|
|
734
|
+
}
|
|
735
|
+
function createErrorBoundary(vnode, parent) {
|
|
736
|
+
const { errorState, handleError, fallback, reset } = vnode.props;
|
|
737
|
+
const children = vnode.children;
|
|
738
|
+
const startComment = document.createComment("eb:start");
|
|
739
|
+
const endComment = document.createComment("eb:end");
|
|
740
|
+
const boundaryCtx = {
|
|
741
|
+
hooks: [],
|
|
742
|
+
hookIndex: 0,
|
|
743
|
+
effects: [],
|
|
744
|
+
cleanups: [],
|
|
745
|
+
mounted: false,
|
|
746
|
+
disposed: false,
|
|
747
|
+
_parentCtx: componentStack[componentStack.length - 1] || null,
|
|
748
|
+
_errorBoundary: handleError,
|
|
749
|
+
_startComment: startComment,
|
|
750
|
+
_endComment: endComment
|
|
751
|
+
};
|
|
752
|
+
_commentCtxMap.set(startComment, boundaryCtx);
|
|
753
|
+
const container = document.createDocumentFragment();
|
|
754
|
+
container._componentCtx = boundaryCtx;
|
|
755
|
+
container.appendChild(startComment);
|
|
756
|
+
container.appendChild(endComment);
|
|
757
|
+
const dispose = effect(() => {
|
|
758
|
+
const error = errorState();
|
|
759
|
+
componentStack.push(boundaryCtx);
|
|
760
|
+
if (startComment.parentNode) {
|
|
761
|
+
while (startComment.nextSibling && startComment.nextSibling !== endComment) {
|
|
762
|
+
const old = startComment.nextSibling;
|
|
763
|
+
disposeTree(old);
|
|
764
|
+
old.parentNode.removeChild(old);
|
|
765
|
+
}
|
|
766
|
+
}
|
|
767
|
+
let vnodes;
|
|
768
|
+
if (error) {
|
|
769
|
+
vnodes = typeof fallback === "function" ? [fallback({ error, reset })] : [fallback];
|
|
770
|
+
} else {
|
|
771
|
+
vnodes = children;
|
|
772
|
+
}
|
|
773
|
+
vnodes = Array.isArray(vnodes) ? vnodes : [vnodes];
|
|
774
|
+
for (const v of vnodes) {
|
|
775
|
+
const node = createDOM(v, parent);
|
|
776
|
+
if (node) {
|
|
777
|
+
if (endComment.parentNode) {
|
|
778
|
+
endComment.parentNode.insertBefore(node, endComment);
|
|
779
|
+
} else {
|
|
780
|
+
container.insertBefore(node, endComment);
|
|
781
|
+
}
|
|
782
|
+
}
|
|
783
|
+
}
|
|
784
|
+
componentStack.pop();
|
|
785
|
+
});
|
|
786
|
+
boundaryCtx.effects.push(dispose);
|
|
787
|
+
return container;
|
|
788
|
+
}
|
|
789
|
+
function createSuspenseBoundary(vnode, parent) {
|
|
790
|
+
const { boundary, fallback, loading } = vnode.props;
|
|
791
|
+
const children = vnode.children;
|
|
792
|
+
const startComment = document.createComment("sb:start");
|
|
793
|
+
const endComment = document.createComment("sb:end");
|
|
794
|
+
const boundaryCtx = {
|
|
795
|
+
hooks: [],
|
|
796
|
+
hookIndex: 0,
|
|
797
|
+
effects: [],
|
|
798
|
+
cleanups: [],
|
|
799
|
+
mounted: false,
|
|
800
|
+
disposed: false,
|
|
801
|
+
_parentCtx: componentStack[componentStack.length - 1] || null,
|
|
802
|
+
_startComment: startComment,
|
|
803
|
+
_endComment: endComment
|
|
804
|
+
};
|
|
805
|
+
_commentCtxMap.set(startComment, boundaryCtx);
|
|
806
|
+
const container = document.createDocumentFragment();
|
|
807
|
+
container._componentCtx = boundaryCtx;
|
|
808
|
+
container.appendChild(startComment);
|
|
809
|
+
container.appendChild(endComment);
|
|
810
|
+
const dispose = effect(() => {
|
|
811
|
+
const isLoading = loading();
|
|
812
|
+
const vnodes = isLoading ? [fallback] : children;
|
|
813
|
+
const normalized = Array.isArray(vnodes) ? vnodes : [vnodes];
|
|
814
|
+
componentStack.push(boundaryCtx);
|
|
815
|
+
if (startComment.parentNode) {
|
|
816
|
+
while (startComment.nextSibling && startComment.nextSibling !== endComment) {
|
|
817
|
+
const old = startComment.nextSibling;
|
|
818
|
+
disposeTree(old);
|
|
819
|
+
old.parentNode.removeChild(old);
|
|
820
|
+
}
|
|
821
|
+
}
|
|
822
|
+
for (const v of normalized) {
|
|
823
|
+
const node = createDOM(v, parent);
|
|
824
|
+
if (node) {
|
|
825
|
+
if (endComment.parentNode) {
|
|
826
|
+
endComment.parentNode.insertBefore(node, endComment);
|
|
827
|
+
} else {
|
|
828
|
+
container.insertBefore(node, endComment);
|
|
829
|
+
}
|
|
830
|
+
}
|
|
831
|
+
}
|
|
832
|
+
componentStack.pop();
|
|
833
|
+
});
|
|
834
|
+
boundaryCtx.effects.push(dispose);
|
|
835
|
+
return container;
|
|
836
|
+
}
|
|
837
|
+
function createPortalDOM(vnode, parent) {
|
|
838
|
+
const { container } = vnode.props;
|
|
839
|
+
const children = vnode.children;
|
|
840
|
+
if (!container) {
|
|
841
|
+
console.warn("[what] Portal: target container not found");
|
|
842
|
+
return document.createComment("portal:empty");
|
|
843
|
+
}
|
|
844
|
+
const portalCtx = {
|
|
845
|
+
hooks: [],
|
|
846
|
+
hookIndex: 0,
|
|
847
|
+
effects: [],
|
|
848
|
+
cleanups: [],
|
|
849
|
+
mounted: false,
|
|
850
|
+
disposed: false,
|
|
851
|
+
_parentCtx: componentStack[componentStack.length - 1] || null
|
|
852
|
+
};
|
|
853
|
+
const placeholder = document.createComment("portal");
|
|
854
|
+
placeholder._componentCtx = portalCtx;
|
|
855
|
+
const portalNodes = [];
|
|
856
|
+
for (const child of children) {
|
|
857
|
+
const node = createDOM(child, container);
|
|
858
|
+
if (node) {
|
|
859
|
+
container.appendChild(node);
|
|
860
|
+
portalNodes.push(node);
|
|
861
|
+
}
|
|
862
|
+
}
|
|
863
|
+
portalCtx._cleanupCallbacks = [() => {
|
|
864
|
+
for (const node of portalNodes) {
|
|
865
|
+
disposeTree(node);
|
|
866
|
+
if (node.parentNode) node.parentNode.removeChild(node);
|
|
867
|
+
}
|
|
868
|
+
}];
|
|
869
|
+
return placeholder;
|
|
870
|
+
}
|
|
871
|
+
function createElementFromVNode(vnode, parent, isSvg) {
|
|
872
|
+
const { tag, props, children } = vnode;
|
|
873
|
+
const svgContext = isSvg || SVG_ELEMENTS.has(tag);
|
|
874
|
+
const el = svgContext ? document.createElementNS(SVG_NS, tag) : document.createElement(tag);
|
|
875
|
+
if (props) {
|
|
876
|
+
applyProps(el, props, {}, svgContext);
|
|
877
|
+
}
|
|
878
|
+
for (const child of children) {
|
|
879
|
+
const node = createDOM(child, el, svgContext && tag !== "foreignObject");
|
|
880
|
+
if (node) el.appendChild(node);
|
|
881
|
+
}
|
|
882
|
+
el._vnode = vnode;
|
|
883
|
+
return el;
|
|
884
|
+
}
|
|
885
|
+
function applyProps(el, newProps, oldProps, isSvg) {
|
|
886
|
+
newProps = newProps || {};
|
|
887
|
+
oldProps = oldProps || {};
|
|
888
|
+
for (const key in newProps) {
|
|
889
|
+
if (key === "key" || key === "children") continue;
|
|
890
|
+
if (key === "ref") {
|
|
891
|
+
if (typeof newProps.ref === "function") newProps.ref(el);
|
|
892
|
+
else if (newProps.ref) newProps.ref.current = el;
|
|
893
|
+
continue;
|
|
894
|
+
}
|
|
895
|
+
setProp(el, key, newProps[key], isSvg);
|
|
896
|
+
}
|
|
897
|
+
}
|
|
898
|
+
function setProp(el, key, value, isSvg) {
|
|
899
|
+
if (key.startsWith("on") && key.length > 2) {
|
|
900
|
+
let eventName = key.slice(2);
|
|
901
|
+
let useCapture = false;
|
|
902
|
+
if (eventName.endsWith("Capture")) {
|
|
903
|
+
eventName = eventName.slice(0, -7);
|
|
904
|
+
useCapture = true;
|
|
905
|
+
}
|
|
906
|
+
const event = eventName.toLowerCase();
|
|
907
|
+
const storageKey = useCapture ? event + "_capture" : event;
|
|
908
|
+
const old = el._events?.[storageKey];
|
|
909
|
+
if (old && old._original === value) return;
|
|
910
|
+
if (old) el.removeEventListener(event, old, useCapture);
|
|
911
|
+
if (value == null) return;
|
|
912
|
+
if (!el._events) el._events = {};
|
|
913
|
+
const wrappedHandler = (e) => {
|
|
914
|
+
if (!e.nativeEvent) e.nativeEvent = e;
|
|
915
|
+
return untrack(() => value(e));
|
|
916
|
+
};
|
|
917
|
+
wrappedHandler._original = value;
|
|
918
|
+
el._events[storageKey] = wrappedHandler;
|
|
919
|
+
const eventOpts = value._eventOpts;
|
|
920
|
+
el.addEventListener(event, wrappedHandler, eventOpts || useCapture || void 0);
|
|
921
|
+
return;
|
|
922
|
+
}
|
|
923
|
+
if (key === "ref") {
|
|
924
|
+
if (typeof value === "function") value(el);
|
|
925
|
+
else if (value) value.current = el;
|
|
926
|
+
return;
|
|
927
|
+
}
|
|
928
|
+
if (!isSafeUrlAttributeValue(key, value)) {
|
|
929
|
+
if (typeof console !== "undefined") {
|
|
930
|
+
console.warn(`[what] Blocked unsafe URL in "${key}" attribute: ${value}`);
|
|
931
|
+
}
|
|
932
|
+
el.removeAttribute(getDomAttributeName(key));
|
|
933
|
+
return;
|
|
934
|
+
}
|
|
935
|
+
if (typeof value === "function") {
|
|
936
|
+
if (!el._propEffects) el._propEffects = {};
|
|
937
|
+
if (el._propEffects[key]) {
|
|
938
|
+
try {
|
|
939
|
+
el._propEffects[key]();
|
|
940
|
+
} catch (e) {
|
|
941
|
+
}
|
|
942
|
+
}
|
|
943
|
+
el._propEffects[key] = effect(() => {
|
|
944
|
+
const resolved = value();
|
|
945
|
+
setProp(el, key, resolved, isSvg);
|
|
946
|
+
});
|
|
947
|
+
return;
|
|
948
|
+
}
|
|
949
|
+
if (key === "className" || key === "class") {
|
|
950
|
+
if (isSvg) {
|
|
951
|
+
el.setAttribute("class", value || "");
|
|
952
|
+
} else {
|
|
953
|
+
el.className = value || "";
|
|
954
|
+
}
|
|
955
|
+
return;
|
|
956
|
+
}
|
|
957
|
+
if (key === "style") {
|
|
958
|
+
if (typeof value === "string") {
|
|
959
|
+
el.style.cssText = value;
|
|
960
|
+
el._prevStyle = null;
|
|
961
|
+
} else if (typeof value === "object") {
|
|
962
|
+
const oldStyle = el._prevStyle || {};
|
|
963
|
+
for (const prop in oldStyle) {
|
|
964
|
+
if (!(prop in value)) el.style[prop] = "";
|
|
965
|
+
}
|
|
966
|
+
for (const prop in value) {
|
|
967
|
+
el.style[prop] = value[prop] ?? "";
|
|
968
|
+
}
|
|
969
|
+
el._prevStyle = { ...value };
|
|
970
|
+
}
|
|
971
|
+
return;
|
|
972
|
+
}
|
|
973
|
+
if (key === "dangerouslySetInnerHTML") {
|
|
974
|
+
el.innerHTML = value?.__html ?? "";
|
|
975
|
+
return;
|
|
976
|
+
}
|
|
977
|
+
if (key === "innerHTML") {
|
|
978
|
+
if (value == null) return;
|
|
979
|
+
if (value && typeof value === "object" && "__html" in value) {
|
|
980
|
+
el.innerHTML = value.__html ?? "";
|
|
981
|
+
} else {
|
|
982
|
+
if (__DEV__) {
|
|
983
|
+
console.warn(
|
|
984
|
+
"[what] innerHTML received a raw string. This is a security risk (XSS). Use innerHTML={{ __html: trustedString }} or dangerouslySetInnerHTML={{ __html: trustedString }} instead."
|
|
985
|
+
);
|
|
986
|
+
}
|
|
987
|
+
return;
|
|
988
|
+
}
|
|
989
|
+
return;
|
|
990
|
+
}
|
|
991
|
+
if (typeof value === "boolean") {
|
|
992
|
+
if (value) el.setAttribute(key, "");
|
|
993
|
+
else el.removeAttribute(key);
|
|
994
|
+
return;
|
|
995
|
+
}
|
|
996
|
+
if (key.startsWith("data-") || key.startsWith("aria-")) {
|
|
997
|
+
el.setAttribute(key, value);
|
|
998
|
+
return;
|
|
999
|
+
}
|
|
1000
|
+
if (isSvg) {
|
|
1001
|
+
if (value === false || value == null) {
|
|
1002
|
+
el.removeAttribute(key);
|
|
1003
|
+
} else {
|
|
1004
|
+
el.setAttribute(key, value === true ? "" : String(value));
|
|
1005
|
+
}
|
|
1006
|
+
return;
|
|
1007
|
+
}
|
|
1008
|
+
if (key in el) {
|
|
1009
|
+
el[key] = value;
|
|
1010
|
+
} else {
|
|
1011
|
+
el.setAttribute(key, value);
|
|
1012
|
+
}
|
|
1013
|
+
}
|
|
1014
|
+
|
|
1015
|
+
// packages/core/src/render.js
|
|
1016
|
+
function _$createComponent(Component, props, children) {
|
|
1017
|
+
if (children && children.length > 0) {
|
|
1018
|
+
const mergedChildren = children.length === 1 ? children[0] : children;
|
|
1019
|
+
props = props ? { ...props, children: mergedChildren } : { children: mergedChildren };
|
|
1020
|
+
}
|
|
1021
|
+
return createDOM({ tag: Component, props: props || {}, children: children || [], key: null, _vnode: true });
|
|
1022
|
+
}
|
|
1023
|
+
var TABLE_WRAPPERS = {
|
|
1024
|
+
tr: { depth: 2, wrap: "<table><tbody>", unwrap: "</tbody></table>" },
|
|
1025
|
+
td: { depth: 3, wrap: "<table><tbody><tr>", unwrap: "</tr></tbody></table>" },
|
|
1026
|
+
th: { depth: 3, wrap: "<table><tbody><tr>", unwrap: "</tr></tbody></table>" },
|
|
1027
|
+
thead: { depth: 1, wrap: "<table>", unwrap: "</table>" },
|
|
1028
|
+
tbody: { depth: 1, wrap: "<table>", unwrap: "</table>" },
|
|
1029
|
+
tfoot: { depth: 1, wrap: "<table>", unwrap: "</table>" },
|
|
1030
|
+
colgroup: { depth: 1, wrap: "<table>", unwrap: "</table>" },
|
|
1031
|
+
col: { depth: 1, wrap: "<table>", unwrap: "</table>" },
|
|
1032
|
+
caption: { depth: 1, wrap: "<table>", unwrap: "</table>" }
|
|
1033
|
+
};
|
|
1034
|
+
var SVG_ELEMENTS2 = /* @__PURE__ */ new Set([
|
|
1035
|
+
"svg",
|
|
1036
|
+
"path",
|
|
1037
|
+
"circle",
|
|
1038
|
+
"rect",
|
|
1039
|
+
"line",
|
|
1040
|
+
"polyline",
|
|
1041
|
+
"polygon",
|
|
1042
|
+
"ellipse",
|
|
1043
|
+
"g",
|
|
1044
|
+
"defs",
|
|
1045
|
+
"use",
|
|
1046
|
+
"text",
|
|
1047
|
+
"tspan",
|
|
1048
|
+
"foreignObject",
|
|
1049
|
+
"clipPath",
|
|
1050
|
+
"mask",
|
|
1051
|
+
"pattern",
|
|
1052
|
+
"linearGradient",
|
|
1053
|
+
"radialGradient",
|
|
1054
|
+
"stop",
|
|
1055
|
+
"marker",
|
|
1056
|
+
"symbol",
|
|
1057
|
+
"image",
|
|
1058
|
+
"animate",
|
|
1059
|
+
"animateTransform",
|
|
1060
|
+
"animateMotion",
|
|
1061
|
+
"set",
|
|
1062
|
+
"filter",
|
|
1063
|
+
"feGaussianBlur",
|
|
1064
|
+
"feOffset",
|
|
1065
|
+
"feMerge",
|
|
1066
|
+
"feMergeNode",
|
|
1067
|
+
"feBlend",
|
|
1068
|
+
"feColorMatrix",
|
|
1069
|
+
"feComponentTransfer",
|
|
1070
|
+
"feComposite",
|
|
1071
|
+
"feConvolveMatrix",
|
|
1072
|
+
"feDiffuseLighting",
|
|
1073
|
+
"feDisplacementMap",
|
|
1074
|
+
"feFlood",
|
|
1075
|
+
"feImage",
|
|
1076
|
+
"feMorphology",
|
|
1077
|
+
"feSpecularLighting",
|
|
1078
|
+
"feTile",
|
|
1079
|
+
"feTurbulence",
|
|
1080
|
+
"feDistantLight",
|
|
1081
|
+
"fePointLight",
|
|
1082
|
+
"feSpotLight"
|
|
1083
|
+
]);
|
|
1084
|
+
function getLeadingTag(html) {
|
|
1085
|
+
const m = html.match(/^<([a-zA-Z][a-zA-Z0-9]*)/);
|
|
1086
|
+
return m ? m[1] : "";
|
|
1087
|
+
}
|
|
1088
|
+
function _$templateImpl(html) {
|
|
1089
|
+
const trimmed = html.trim();
|
|
1090
|
+
const tag = getLeadingTag(trimmed);
|
|
1091
|
+
if (SVG_ELEMENTS2.has(tag)) {
|
|
1092
|
+
return svgTemplate(trimmed);
|
|
1093
|
+
}
|
|
1094
|
+
const tableInfo = TABLE_WRAPPERS[tag];
|
|
1095
|
+
if (tableInfo) {
|
|
1096
|
+
const t2 = document.createElement("template");
|
|
1097
|
+
t2.innerHTML = tableInfo.wrap + trimmed + tableInfo.unwrap;
|
|
1098
|
+
return () => {
|
|
1099
|
+
let node = t2.content.firstChild;
|
|
1100
|
+
for (let i = 0; i < tableInfo.depth; i++) {
|
|
1101
|
+
node = node.firstChild;
|
|
1102
|
+
}
|
|
1103
|
+
return node.cloneNode(true);
|
|
1104
|
+
};
|
|
1105
|
+
}
|
|
1106
|
+
const t = document.createElement("template");
|
|
1107
|
+
t.innerHTML = trimmed;
|
|
1108
|
+
return () => t.content.firstChild.cloneNode(true);
|
|
1109
|
+
}
|
|
1110
|
+
var _templateWarned = false;
|
|
1111
|
+
function template(html) {
|
|
1112
|
+
if (__DEV__ && !_templateWarned) {
|
|
1113
|
+
_templateWarned = true;
|
|
1114
|
+
console.warn(
|
|
1115
|
+
"[what] template() is a compiler internal. Use JSX instead. Direct calls with user input can lead to XSS vulnerabilities."
|
|
1116
|
+
);
|
|
1117
|
+
}
|
|
1118
|
+
return _$templateImpl(html);
|
|
1119
|
+
}
|
|
1120
|
+
function svgTemplate(html) {
|
|
1121
|
+
const trimmed = html.trim();
|
|
1122
|
+
const tag = getLeadingTag(trimmed);
|
|
1123
|
+
if (tag === "svg") {
|
|
1124
|
+
const t2 = document.createElement("template");
|
|
1125
|
+
t2.innerHTML = trimmed;
|
|
1126
|
+
return () => t2.content.firstChild.cloneNode(true);
|
|
1127
|
+
}
|
|
1128
|
+
const t = document.createElement("template");
|
|
1129
|
+
t.innerHTML = `<svg xmlns="http://www.w3.org/2000/svg">${trimmed}</svg>`;
|
|
1130
|
+
return () => t.content.firstChild.firstChild.cloneNode(true);
|
|
1131
|
+
}
|
|
1132
|
+
function insert(parent, child, marker) {
|
|
1133
|
+
if (typeof child === "function") {
|
|
1134
|
+
let current = null;
|
|
1135
|
+
effect(() => {
|
|
1136
|
+
current = reconcileInsert(parent, child(), current, marker || null);
|
|
1137
|
+
});
|
|
1138
|
+
return current;
|
|
1139
|
+
}
|
|
1140
|
+
return reconcileInsert(parent, child, null, marker || null);
|
|
1141
|
+
}
|
|
1142
|
+
function isDomNode2(value) {
|
|
1143
|
+
if (!value || typeof value !== "object") return false;
|
|
1144
|
+
if (typeof Node !== "undefined" && value instanceof Node) return true;
|
|
1145
|
+
return typeof value.nodeType === "number" && typeof value.nodeName === "string";
|
|
1146
|
+
}
|
|
1147
|
+
function isVNode2(value) {
|
|
1148
|
+
return !!value && typeof value === "object" && (value._vnode === true || "tag" in value);
|
|
1149
|
+
}
|
|
1150
|
+
function isSvgParent(parent) {
|
|
1151
|
+
return typeof SVGElement !== "undefined" && parent instanceof SVGElement && parent.tagName.toLowerCase() !== "foreignobject";
|
|
1152
|
+
}
|
|
1153
|
+
function asNodeArray(value) {
|
|
1154
|
+
if (value == null) return [];
|
|
1155
|
+
return Array.isArray(value) ? value : [value];
|
|
1156
|
+
}
|
|
1157
|
+
function valuesToNodes(value, parent, out) {
|
|
1158
|
+
if (value == null || typeof value === "boolean") return out;
|
|
1159
|
+
if (Array.isArray(value)) {
|
|
1160
|
+
for (let i = 0; i < value.length; i++) {
|
|
1161
|
+
valuesToNodes(value[i], parent, out);
|
|
1162
|
+
}
|
|
1163
|
+
return out;
|
|
1164
|
+
}
|
|
1165
|
+
if (typeof value === "string" || typeof value === "number") {
|
|
1166
|
+
out.push(document.createTextNode(String(value)));
|
|
1167
|
+
return out;
|
|
1168
|
+
}
|
|
1169
|
+
if (isDomNode2(value)) {
|
|
1170
|
+
out.push(value);
|
|
1171
|
+
return out;
|
|
1172
|
+
}
|
|
1173
|
+
if (isVNode2(value)) {
|
|
1174
|
+
out.push(createDOM(value, parent, isSvgParent(parent)));
|
|
1175
|
+
return out;
|
|
1176
|
+
}
|
|
1177
|
+
out.push(document.createTextNode(String(value)));
|
|
1178
|
+
return out;
|
|
1179
|
+
}
|
|
1180
|
+
function sameNodeArray(a, b) {
|
|
1181
|
+
if (a.length !== b.length) return false;
|
|
1182
|
+
for (let i = 0; i < a.length; i++) {
|
|
1183
|
+
if (a[i] !== b[i]) return false;
|
|
1184
|
+
}
|
|
1185
|
+
return true;
|
|
1186
|
+
}
|
|
1187
|
+
function reconcileInsert(parent, value, current, marker) {
|
|
1188
|
+
if (!parent || typeof parent.insertBefore !== "function") {
|
|
1189
|
+
if (__DEV__) {
|
|
1190
|
+
console.warn("[what] reconcileInsert called with invalid parent:", parent);
|
|
1191
|
+
}
|
|
1192
|
+
return current;
|
|
1193
|
+
}
|
|
1194
|
+
const targetMarker = marker || null;
|
|
1195
|
+
if (value == null || typeof value === "boolean") {
|
|
1196
|
+
const oldNodes2 = asNodeArray(current);
|
|
1197
|
+
for (let i = 0; i < oldNodes2.length; i++) {
|
|
1198
|
+
const oldNode = oldNodes2[i];
|
|
1199
|
+
if (oldNode.parentNode === parent) {
|
|
1200
|
+
disposeTree(oldNode);
|
|
1201
|
+
parent.removeChild(oldNode);
|
|
1202
|
+
}
|
|
1203
|
+
}
|
|
1204
|
+
return null;
|
|
1205
|
+
}
|
|
1206
|
+
if ((typeof value === "string" || typeof value === "number") && current && !Array.isArray(current) && current.nodeType === 3) {
|
|
1207
|
+
const text = String(value);
|
|
1208
|
+
if (current.textContent !== text) current.textContent = text;
|
|
1209
|
+
return current;
|
|
1210
|
+
}
|
|
1211
|
+
const newNodes = valuesToNodes(value, parent, []);
|
|
1212
|
+
const oldNodes = asNodeArray(current);
|
|
1213
|
+
if (sameNodeArray(oldNodes, newNodes)) {
|
|
1214
|
+
return current;
|
|
1215
|
+
}
|
|
1216
|
+
const keep = new Set(newNodes);
|
|
1217
|
+
for (let i = 0; i < oldNodes.length; i++) {
|
|
1218
|
+
const oldNode = oldNodes[i];
|
|
1219
|
+
if (!keep.has(oldNode) && oldNode.parentNode === parent) {
|
|
1220
|
+
disposeTree(oldNode);
|
|
1221
|
+
parent.removeChild(oldNode);
|
|
1222
|
+
}
|
|
1223
|
+
}
|
|
1224
|
+
let ref = targetMarker;
|
|
1225
|
+
for (let i = newNodes.length - 1; i >= 0; i--) {
|
|
1226
|
+
const node = newNodes[i];
|
|
1227
|
+
if (node.parentNode !== parent || node.nextSibling !== ref) {
|
|
1228
|
+
if (ref && ref.parentNode !== parent) ref = null;
|
|
1229
|
+
if (ref) parent.insertBefore(node, ref);
|
|
1230
|
+
else parent.appendChild(node);
|
|
1231
|
+
}
|
|
1232
|
+
ref = node;
|
|
1233
|
+
}
|
|
1234
|
+
if (newNodes.length === 0) return null;
|
|
1235
|
+
return newNodes.length === 1 ? newNodes[0] : newNodes;
|
|
1236
|
+
}
|
|
1237
|
+
function mapArray(source, mapFn, options) {
|
|
1238
|
+
const keyFn = options?.key;
|
|
1239
|
+
const raw = options?.raw || false;
|
|
1240
|
+
return (parent, marker) => {
|
|
1241
|
+
let items = [];
|
|
1242
|
+
let mappedNodes = [];
|
|
1243
|
+
let disposeFns = [];
|
|
1244
|
+
let keyedState = keyFn && !raw ? /* @__PURE__ */ new Map() : null;
|
|
1245
|
+
const endMarker = document.createComment("/list");
|
|
1246
|
+
parent.insertBefore(endMarker, marker || null);
|
|
1247
|
+
effect(() => {
|
|
1248
|
+
const newItems = source() || [];
|
|
1249
|
+
if (keyFn) {
|
|
1250
|
+
reconcileKeyed(parent, endMarker, items, newItems, mappedNodes, disposeFns, mapFn, keyFn, keyedState);
|
|
1251
|
+
} else {
|
|
1252
|
+
reconcileList(parent, endMarker, items, newItems, mappedNodes, disposeFns, mapFn);
|
|
1253
|
+
}
|
|
1254
|
+
items = newItems.slice();
|
|
1255
|
+
});
|
|
1256
|
+
return endMarker;
|
|
1257
|
+
};
|
|
1258
|
+
}
|
|
1259
|
+
function reconcileList(parent, endMarker, oldItems, newItems, mappedNodes, disposeFns, mapFn) {
|
|
1260
|
+
const newLen = newItems.length;
|
|
1261
|
+
const oldLen = oldItems.length;
|
|
1262
|
+
if (newLen === 0) {
|
|
1263
|
+
if (oldLen > 0) {
|
|
1264
|
+
for (let i = 0; i < oldLen; i++) {
|
|
1265
|
+
disposeFns[i]?.();
|
|
1266
|
+
if (mappedNodes[i]?.parentNode === parent) {
|
|
1267
|
+
disposeTree(mappedNodes[i]);
|
|
1268
|
+
parent.removeChild(mappedNodes[i]);
|
|
1269
|
+
}
|
|
1270
|
+
}
|
|
1271
|
+
mappedNodes.length = 0;
|
|
1272
|
+
disposeFns.length = 0;
|
|
1273
|
+
}
|
|
1274
|
+
return;
|
|
1275
|
+
}
|
|
1276
|
+
if (oldLen === 0) {
|
|
1277
|
+
const frag = document.createDocumentFragment();
|
|
1278
|
+
for (let i = 0; i < newLen; i++) {
|
|
1279
|
+
const item = newItems[i];
|
|
1280
|
+
const node = createRoot((dispose) => {
|
|
1281
|
+
disposeFns[i] = dispose;
|
|
1282
|
+
return mapFn(item, i);
|
|
1283
|
+
});
|
|
1284
|
+
mappedNodes[i] = node;
|
|
1285
|
+
frag.appendChild(node);
|
|
1286
|
+
}
|
|
1287
|
+
parent.insertBefore(frag, endMarker);
|
|
1288
|
+
return;
|
|
1289
|
+
}
|
|
1290
|
+
let start = 0;
|
|
1291
|
+
const minLen = Math.min(oldLen, newLen);
|
|
1292
|
+
while (start < minLen && oldItems[start] === newItems[start]) start++;
|
|
1293
|
+
if (start === oldLen && start === newLen) return;
|
|
1294
|
+
let oldEnd = oldLen - 1;
|
|
1295
|
+
let newEnd = newLen - 1;
|
|
1296
|
+
while (oldEnd >= start && newEnd >= start && oldItems[oldEnd] === newItems[newEnd]) {
|
|
1297
|
+
oldEnd--;
|
|
1298
|
+
newEnd--;
|
|
1299
|
+
}
|
|
1300
|
+
const newMapped = new Array(newLen);
|
|
1301
|
+
const newDispose = new Array(newLen);
|
|
1302
|
+
for (let i = 0; i < start; i++) {
|
|
1303
|
+
newMapped[i] = mappedNodes[i];
|
|
1304
|
+
newDispose[i] = disposeFns[i];
|
|
1305
|
+
}
|
|
1306
|
+
for (let i = newEnd + 1; i < newLen; i++) {
|
|
1307
|
+
const oldI = oldEnd + 1 + (i - newEnd - 1);
|
|
1308
|
+
newMapped[i] = mappedNodes[oldI];
|
|
1309
|
+
newDispose[i] = disposeFns[oldI];
|
|
1310
|
+
}
|
|
1311
|
+
const midNewLen = newEnd - start + 1;
|
|
1312
|
+
const midOldLen = oldEnd - start + 1;
|
|
1313
|
+
if (midNewLen === 0) {
|
|
1314
|
+
for (let i = start; i <= oldEnd; i++) {
|
|
1315
|
+
disposeFns[i]?.();
|
|
1316
|
+
if (mappedNodes[i]?.parentNode) mappedNodes[i].parentNode.removeChild(mappedNodes[i]);
|
|
1317
|
+
}
|
|
1318
|
+
} else if (midOldLen === 0) {
|
|
1319
|
+
const marker = start < newLen && newMapped[newEnd + 1] ? newMapped[newEnd + 1] : endMarker;
|
|
1320
|
+
const frag = document.createDocumentFragment();
|
|
1321
|
+
for (let i = start; i <= newEnd; i++) {
|
|
1322
|
+
const item = newItems[i];
|
|
1323
|
+
const idx = i;
|
|
1324
|
+
newMapped[i] = createRoot((dispose) => {
|
|
1325
|
+
newDispose[idx] = dispose;
|
|
1326
|
+
return mapFn(item, idx);
|
|
1327
|
+
});
|
|
1328
|
+
frag.appendChild(newMapped[i]);
|
|
1329
|
+
}
|
|
1330
|
+
parent.insertBefore(frag, marker);
|
|
1331
|
+
} else {
|
|
1332
|
+
_reconcileMiddle(
|
|
1333
|
+
parent,
|
|
1334
|
+
endMarker,
|
|
1335
|
+
oldItems,
|
|
1336
|
+
newItems,
|
|
1337
|
+
mappedNodes,
|
|
1338
|
+
disposeFns,
|
|
1339
|
+
mapFn,
|
|
1340
|
+
start,
|
|
1341
|
+
oldEnd,
|
|
1342
|
+
newEnd,
|
|
1343
|
+
newMapped,
|
|
1344
|
+
newDispose
|
|
1345
|
+
);
|
|
1346
|
+
}
|
|
1347
|
+
mappedNodes.length = newLen;
|
|
1348
|
+
disposeFns.length = newLen;
|
|
1349
|
+
for (let i = 0; i < newLen; i++) {
|
|
1350
|
+
mappedNodes[i] = newMapped[i];
|
|
1351
|
+
disposeFns[i] = newDispose[i];
|
|
1352
|
+
}
|
|
1353
|
+
}
|
|
1354
|
+
function _reconcileMiddle(parent, endMarker, oldItems, newItems, mappedNodes, disposeFns, mapFn, start, oldEnd, newEnd, newMapped, newDispose) {
|
|
1355
|
+
const oldIdxMap = /* @__PURE__ */ new Map();
|
|
1356
|
+
for (let i = start; i <= oldEnd; i++) {
|
|
1357
|
+
oldIdxMap.set(oldItems[i], i);
|
|
1358
|
+
}
|
|
1359
|
+
const midLen = newEnd - start + 1;
|
|
1360
|
+
const oldIndices = new Int32Array(midLen);
|
|
1361
|
+
oldIndices.fill(-1);
|
|
1362
|
+
for (let i = start; i <= newEnd; i++) {
|
|
1363
|
+
const oldIdx = oldIdxMap.get(newItems[i]);
|
|
1364
|
+
if (oldIdx !== void 0) {
|
|
1365
|
+
oldIdxMap.delete(newItems[i]);
|
|
1366
|
+
newMapped[i] = mappedNodes[oldIdx];
|
|
1367
|
+
newDispose[i] = disposeFns[oldIdx];
|
|
1368
|
+
oldIndices[i - start] = oldIdx;
|
|
1369
|
+
}
|
|
1370
|
+
}
|
|
1371
|
+
for (const [, oldIdx] of oldIdxMap) {
|
|
1372
|
+
disposeFns[oldIdx]?.();
|
|
1373
|
+
if (mappedNodes[oldIdx]?.parentNode) mappedNodes[oldIdx].parentNode.removeChild(mappedNodes[oldIdx]);
|
|
1374
|
+
}
|
|
1375
|
+
const reusedCount = midLen - _countNeg1(oldIndices, midLen);
|
|
1376
|
+
const inLIS = new Uint8Array(midLen);
|
|
1377
|
+
if (reusedCount > 1) {
|
|
1378
|
+
const seq = new Int32Array(reusedCount);
|
|
1379
|
+
const seqToMid = new Int32Array(reusedCount);
|
|
1380
|
+
let k = 0;
|
|
1381
|
+
for (let i = 0; i < midLen; i++) {
|
|
1382
|
+
if (oldIndices[i] !== -1) {
|
|
1383
|
+
seq[k] = oldIndices[i];
|
|
1384
|
+
seqToMid[k] = i;
|
|
1385
|
+
k++;
|
|
1386
|
+
}
|
|
1387
|
+
}
|
|
1388
|
+
const lisResult = _lis(seq, reusedCount);
|
|
1389
|
+
for (let i = 0; i < lisResult.length; i++) {
|
|
1390
|
+
inLIS[seqToMid[lisResult[i]]] = 1;
|
|
1391
|
+
}
|
|
1392
|
+
} else if (reusedCount === 1) {
|
|
1393
|
+
for (let i = 0; i < midLen; i++) {
|
|
1394
|
+
if (oldIndices[i] !== -1) {
|
|
1395
|
+
inLIS[i] = 1;
|
|
1396
|
+
break;
|
|
1397
|
+
}
|
|
1398
|
+
}
|
|
1399
|
+
}
|
|
1400
|
+
for (let i = start; i <= newEnd; i++) {
|
|
1401
|
+
if (!newMapped[i]) {
|
|
1402
|
+
const item = newItems[i];
|
|
1403
|
+
const idx = i;
|
|
1404
|
+
newMapped[i] = createRoot((dispose) => {
|
|
1405
|
+
newDispose[idx] = dispose;
|
|
1406
|
+
return mapFn(item, idx);
|
|
1407
|
+
});
|
|
1408
|
+
}
|
|
1409
|
+
}
|
|
1410
|
+
let nextSibling = newEnd + 1 < newMapped.length && newMapped[newEnd + 1] ? newMapped[newEnd + 1] : endMarker;
|
|
1411
|
+
for (let i = newEnd; i >= start; i--) {
|
|
1412
|
+
const mi = i - start;
|
|
1413
|
+
if (oldIndices[mi] === -1 || !inLIS[mi]) {
|
|
1414
|
+
if (nextSibling && nextSibling.parentNode !== parent) nextSibling = endMarker;
|
|
1415
|
+
parent.insertBefore(newMapped[i], nextSibling);
|
|
1416
|
+
}
|
|
1417
|
+
nextSibling = newMapped[i];
|
|
1418
|
+
}
|
|
1419
|
+
}
|
|
1420
|
+
function _countNeg1(arr, len) {
|
|
1421
|
+
let c = 0;
|
|
1422
|
+
for (let i = 0; i < len; i++) if (arr[i] === -1) c++;
|
|
1423
|
+
return c;
|
|
1424
|
+
}
|
|
1425
|
+
function _lis(arr, len) {
|
|
1426
|
+
if (len === 0) return [];
|
|
1427
|
+
if (len === 1) return [0];
|
|
1428
|
+
const tails = new Int32Array(len);
|
|
1429
|
+
const predecessors = new Int32Array(len);
|
|
1430
|
+
let tailLen = 1;
|
|
1431
|
+
tails[0] = 0;
|
|
1432
|
+
predecessors[0] = -1;
|
|
1433
|
+
for (let i = 1; i < len; i++) {
|
|
1434
|
+
if (arr[i] > arr[tails[tailLen - 1]]) {
|
|
1435
|
+
predecessors[i] = tails[tailLen - 1];
|
|
1436
|
+
tails[tailLen++] = i;
|
|
1437
|
+
} else {
|
|
1438
|
+
let lo = 0, hi = tailLen - 1;
|
|
1439
|
+
while (lo < hi) {
|
|
1440
|
+
const mid = lo + hi >> 1;
|
|
1441
|
+
if (arr[tails[mid]] < arr[i]) lo = mid + 1;
|
|
1442
|
+
else hi = mid;
|
|
1443
|
+
}
|
|
1444
|
+
tails[lo] = i;
|
|
1445
|
+
predecessors[i] = lo > 0 ? tails[lo - 1] : -1;
|
|
1446
|
+
}
|
|
1447
|
+
}
|
|
1448
|
+
const result = new Array(tailLen);
|
|
1449
|
+
let k = tails[tailLen - 1];
|
|
1450
|
+
for (let i = tailLen - 1; i >= 0; i--) {
|
|
1451
|
+
result[i] = k;
|
|
1452
|
+
k = predecessors[k];
|
|
1453
|
+
}
|
|
1454
|
+
return result;
|
|
1455
|
+
}
|
|
1456
|
+
function reconcileKeyed(parent, endMarker, oldItems, newItems, mappedNodes, disposeFns, mapFn, keyFn, keyedState) {
|
|
1457
|
+
const newLen = newItems.length;
|
|
1458
|
+
const oldLen = oldItems.length;
|
|
1459
|
+
if (newLen === 0) {
|
|
1460
|
+
if (oldLen > 0) {
|
|
1461
|
+
for (let i = 0; i < oldLen; i++) {
|
|
1462
|
+
disposeFns[i]?.();
|
|
1463
|
+
if (mappedNodes[i]?.parentNode === parent) {
|
|
1464
|
+
disposeTree(mappedNodes[i]);
|
|
1465
|
+
parent.removeChild(mappedNodes[i]);
|
|
1466
|
+
}
|
|
1467
|
+
}
|
|
1468
|
+
mappedNodes.length = 0;
|
|
1469
|
+
disposeFns.length = 0;
|
|
1470
|
+
if (keyedState) keyedState.clear();
|
|
1471
|
+
}
|
|
1472
|
+
return;
|
|
1473
|
+
}
|
|
1474
|
+
if (oldLen === 0) {
|
|
1475
|
+
const frag = document.createDocumentFragment();
|
|
1476
|
+
for (let i = 0; i < newLen; i++) {
|
|
1477
|
+
const item = newItems[i];
|
|
1478
|
+
const idx = i;
|
|
1479
|
+
let accessor;
|
|
1480
|
+
if (keyedState) {
|
|
1481
|
+
const key = keyFn(item);
|
|
1482
|
+
const itemSig = signal(item);
|
|
1483
|
+
accessor = itemSig;
|
|
1484
|
+
keyedState.set(key, { itemSig });
|
|
1485
|
+
} else {
|
|
1486
|
+
accessor = item;
|
|
1487
|
+
}
|
|
1488
|
+
const node = createRoot((dispose) => {
|
|
1489
|
+
disposeFns[idx] = dispose;
|
|
1490
|
+
return mapFn(accessor, idx);
|
|
1491
|
+
});
|
|
1492
|
+
mappedNodes[i] = node;
|
|
1493
|
+
frag.appendChild(node);
|
|
1494
|
+
}
|
|
1495
|
+
parent.insertBefore(frag, endMarker);
|
|
1496
|
+
return;
|
|
1497
|
+
}
|
|
1498
|
+
let start = 0;
|
|
1499
|
+
const minLen = Math.min(oldLen, newLen);
|
|
1500
|
+
while (start < minLen) {
|
|
1501
|
+
if (oldItems[start] === newItems[start]) {
|
|
1502
|
+
start++;
|
|
1503
|
+
continue;
|
|
1504
|
+
}
|
|
1505
|
+
const oldKey = keyFn(oldItems[start]);
|
|
1506
|
+
const newKey = keyFn(newItems[start]);
|
|
1507
|
+
if (oldKey !== newKey) break;
|
|
1508
|
+
if (keyedState) keyedState.get(oldKey).itemSig.set(newItems[start]);
|
|
1509
|
+
start++;
|
|
1510
|
+
}
|
|
1511
|
+
let oldEnd = oldLen - 1;
|
|
1512
|
+
let newEnd = newLen - 1;
|
|
1513
|
+
while (oldEnd >= start && newEnd >= start) {
|
|
1514
|
+
if (oldItems[oldEnd] === newItems[newEnd]) {
|
|
1515
|
+
oldEnd--;
|
|
1516
|
+
newEnd--;
|
|
1517
|
+
continue;
|
|
1518
|
+
}
|
|
1519
|
+
const oldKey = keyFn(oldItems[oldEnd]);
|
|
1520
|
+
const newKey = keyFn(newItems[newEnd]);
|
|
1521
|
+
if (oldKey !== newKey) break;
|
|
1522
|
+
if (keyedState) keyedState.get(oldKey).itemSig.set(newItems[newEnd]);
|
|
1523
|
+
oldEnd--;
|
|
1524
|
+
newEnd--;
|
|
1525
|
+
}
|
|
1526
|
+
if (start > oldEnd && start > newEnd) {
|
|
1527
|
+
return;
|
|
1528
|
+
}
|
|
1529
|
+
const newMapped = new Array(newLen);
|
|
1530
|
+
const newDispose = new Array(newLen);
|
|
1531
|
+
for (let i = 0; i < start; i++) {
|
|
1532
|
+
newMapped[i] = mappedNodes[i];
|
|
1533
|
+
newDispose[i] = disposeFns[i];
|
|
1534
|
+
}
|
|
1535
|
+
for (let i = newEnd + 1; i < newLen; i++) {
|
|
1536
|
+
const oldI = oldEnd + 1 + (i - newEnd - 1);
|
|
1537
|
+
newMapped[i] = mappedNodes[oldI];
|
|
1538
|
+
newDispose[i] = disposeFns[oldI];
|
|
1539
|
+
}
|
|
1540
|
+
const midNewLen = newEnd - start + 1;
|
|
1541
|
+
const midOldLen = oldEnd - start + 1;
|
|
1542
|
+
if (midOldLen === 0) {
|
|
1543
|
+
const marker = newEnd + 1 < newLen && newMapped[newEnd + 1] ? newMapped[newEnd + 1] : endMarker;
|
|
1544
|
+
const frag = document.createDocumentFragment();
|
|
1545
|
+
for (let i = start; i <= newEnd; i++) {
|
|
1546
|
+
const item = newItems[i];
|
|
1547
|
+
const idx = i;
|
|
1548
|
+
let accessor;
|
|
1549
|
+
if (keyedState) {
|
|
1550
|
+
const key = keyFn(item);
|
|
1551
|
+
const itemSig = signal(item);
|
|
1552
|
+
accessor = itemSig;
|
|
1553
|
+
keyedState.set(key, { itemSig });
|
|
1554
|
+
} else {
|
|
1555
|
+
accessor = item;
|
|
1556
|
+
}
|
|
1557
|
+
newMapped[i] = createRoot((dispose) => {
|
|
1558
|
+
newDispose[idx] = dispose;
|
|
1559
|
+
return mapFn(accessor, idx);
|
|
1560
|
+
});
|
|
1561
|
+
frag.appendChild(newMapped[i]);
|
|
1562
|
+
}
|
|
1563
|
+
parent.insertBefore(frag, marker);
|
|
1564
|
+
_copyBack(mappedNodes, disposeFns, newMapped, newDispose, newLen);
|
|
1565
|
+
return;
|
|
1566
|
+
}
|
|
1567
|
+
if (midNewLen === 0) {
|
|
1568
|
+
for (let i = start; i <= oldEnd; i++) {
|
|
1569
|
+
disposeFns[i]?.();
|
|
1570
|
+
if (mappedNodes[i]?.parentNode) parent.removeChild(mappedNodes[i]);
|
|
1571
|
+
if (keyedState) keyedState.delete(keyFn(oldItems[i]));
|
|
1572
|
+
}
|
|
1573
|
+
_copyBack(mappedNodes, disposeFns, newMapped, newDispose, newLen);
|
|
1574
|
+
return;
|
|
1575
|
+
}
|
|
1576
|
+
const oldKeyMap = /* @__PURE__ */ new Map();
|
|
1577
|
+
for (let i = start; i <= oldEnd; i++) {
|
|
1578
|
+
oldKeyMap.set(keyFn(oldItems[i]), i);
|
|
1579
|
+
}
|
|
1580
|
+
const oldIndices = new Int32Array(midNewLen);
|
|
1581
|
+
oldIndices.fill(-1);
|
|
1582
|
+
for (let i = start; i <= newEnd; i++) {
|
|
1583
|
+
const key = keyFn(newItems[i]);
|
|
1584
|
+
const oldIdx = oldKeyMap.get(key);
|
|
1585
|
+
if (oldIdx !== void 0) {
|
|
1586
|
+
oldKeyMap.delete(key);
|
|
1587
|
+
newMapped[i] = mappedNodes[oldIdx];
|
|
1588
|
+
newDispose[i] = disposeFns[oldIdx];
|
|
1589
|
+
oldIndices[i - start] = oldIdx;
|
|
1590
|
+
if (keyedState && newItems[i] !== oldItems[oldIdx]) {
|
|
1591
|
+
keyedState.get(key).itemSig.set(newItems[i]);
|
|
1592
|
+
}
|
|
1593
|
+
}
|
|
1594
|
+
}
|
|
1595
|
+
for (const [key, oldIdx] of oldKeyMap) {
|
|
1596
|
+
disposeFns[oldIdx]?.();
|
|
1597
|
+
if (mappedNodes[oldIdx]?.parentNode) parent.removeChild(mappedNodes[oldIdx]);
|
|
1598
|
+
if (keyedState) keyedState.delete(key);
|
|
1599
|
+
}
|
|
1600
|
+
for (let i = start; i <= newEnd; i++) {
|
|
1601
|
+
if (!newMapped[i]) {
|
|
1602
|
+
const item = newItems[i];
|
|
1603
|
+
const idx = i;
|
|
1604
|
+
let accessor;
|
|
1605
|
+
if (keyedState) {
|
|
1606
|
+
const key = keyFn(item);
|
|
1607
|
+
const itemSig = signal(item);
|
|
1608
|
+
accessor = itemSig;
|
|
1609
|
+
keyedState.set(key, { itemSig });
|
|
1610
|
+
} else {
|
|
1611
|
+
accessor = item;
|
|
1612
|
+
}
|
|
1613
|
+
newMapped[i] = createRoot((dispose) => {
|
|
1614
|
+
newDispose[idx] = dispose;
|
|
1615
|
+
return mapFn(accessor, idx);
|
|
1616
|
+
});
|
|
1617
|
+
}
|
|
1618
|
+
}
|
|
1619
|
+
let reusedCount = 0;
|
|
1620
|
+
let alreadySorted = true;
|
|
1621
|
+
let lastOldIdx = -1;
|
|
1622
|
+
for (let i = 0; i < midNewLen; i++) {
|
|
1623
|
+
if (oldIndices[i] !== -1) {
|
|
1624
|
+
reusedCount++;
|
|
1625
|
+
if (oldIndices[i] <= lastOldIdx) alreadySorted = false;
|
|
1626
|
+
lastOldIdx = oldIndices[i];
|
|
1627
|
+
}
|
|
1628
|
+
}
|
|
1629
|
+
const inLIS = new Uint8Array(midNewLen);
|
|
1630
|
+
if (alreadySorted) {
|
|
1631
|
+
for (let i = 0; i < midNewLen; i++) {
|
|
1632
|
+
if (oldIndices[i] !== -1) inLIS[i] = 1;
|
|
1633
|
+
}
|
|
1634
|
+
} else if (reusedCount > 1) {
|
|
1635
|
+
const seq = new Int32Array(reusedCount);
|
|
1636
|
+
const seqToMid = new Int32Array(reusedCount);
|
|
1637
|
+
let k = 0;
|
|
1638
|
+
for (let i = 0; i < midNewLen; i++) {
|
|
1639
|
+
if (oldIndices[i] !== -1) {
|
|
1640
|
+
seq[k] = oldIndices[i];
|
|
1641
|
+
seqToMid[k] = i;
|
|
1642
|
+
k++;
|
|
1643
|
+
}
|
|
1644
|
+
}
|
|
1645
|
+
const lisResult = _lis(seq, reusedCount);
|
|
1646
|
+
for (let i = 0; i < lisResult.length; i++) {
|
|
1647
|
+
inLIS[seqToMid[lisResult[i]]] = 1;
|
|
1648
|
+
}
|
|
1649
|
+
} else if (reusedCount === 1) {
|
|
1650
|
+
for (let i = 0; i < midNewLen; i++) {
|
|
1651
|
+
if (oldIndices[i] !== -1) {
|
|
1652
|
+
inLIS[i] = 1;
|
|
1653
|
+
break;
|
|
1654
|
+
}
|
|
1655
|
+
}
|
|
1656
|
+
}
|
|
1657
|
+
let nextSibling = newEnd + 1 < newMapped.length && newMapped[newEnd + 1] ? newMapped[newEnd + 1] : endMarker;
|
|
1658
|
+
for (let i = newEnd; i >= start; i--) {
|
|
1659
|
+
const mi = i - start;
|
|
1660
|
+
if (oldIndices[mi] === -1 || !inLIS[mi]) {
|
|
1661
|
+
if (nextSibling && nextSibling.parentNode !== parent) nextSibling = endMarker;
|
|
1662
|
+
parent.insertBefore(newMapped[i], nextSibling);
|
|
1663
|
+
}
|
|
1664
|
+
nextSibling = newMapped[i];
|
|
1665
|
+
}
|
|
1666
|
+
_copyBack(mappedNodes, disposeFns, newMapped, newDispose, newLen);
|
|
1667
|
+
}
|
|
1668
|
+
function _copyBack(mappedNodes, disposeFns, newMapped, newDispose, newLen) {
|
|
1669
|
+
mappedNodes.length = newLen;
|
|
1670
|
+
disposeFns.length = newLen;
|
|
1671
|
+
for (let i = 0; i < newLen; i++) {
|
|
1672
|
+
mappedNodes[i] = newMapped[i];
|
|
1673
|
+
disposeFns[i] = newDispose[i];
|
|
1674
|
+
}
|
|
1675
|
+
}
|
|
1676
|
+
function spread(el, props) {
|
|
1677
|
+
for (const key in props) {
|
|
1678
|
+
const value = props[key];
|
|
1679
|
+
if (key.startsWith("on") && key.length > 2) {
|
|
1680
|
+
const event = key.slice(2).toLowerCase();
|
|
1681
|
+
el.addEventListener(event, value);
|
|
1682
|
+
continue;
|
|
1683
|
+
}
|
|
1684
|
+
if (typeof value === "function" && !key.startsWith("on")) {
|
|
1685
|
+
if (key === "class" || key === "className") {
|
|
1686
|
+
effect(() => {
|
|
1687
|
+
el.className = value() || "";
|
|
1688
|
+
});
|
|
1689
|
+
} else if (key === "style" && typeof value() === "object") {
|
|
1690
|
+
effect(() => {
|
|
1691
|
+
const styles = value();
|
|
1692
|
+
for (const prop in styles) {
|
|
1693
|
+
el.style[prop] = styles[prop] ?? "";
|
|
1694
|
+
}
|
|
1695
|
+
});
|
|
1696
|
+
} else {
|
|
1697
|
+
effect(() => {
|
|
1698
|
+
setProp2(el, key, value());
|
|
1699
|
+
});
|
|
1700
|
+
}
|
|
1701
|
+
} else {
|
|
1702
|
+
setProp2(el, key, value);
|
|
1703
|
+
}
|
|
1704
|
+
}
|
|
1705
|
+
}
|
|
1706
|
+
function setProp2(el, key, value) {
|
|
1707
|
+
if (key === "ref") {
|
|
1708
|
+
if (typeof value === "function") value(el);
|
|
1709
|
+
else if (value && typeof value === "object") value.current = el;
|
|
1710
|
+
return;
|
|
1711
|
+
}
|
|
1712
|
+
if (key === "key") return;
|
|
1713
|
+
if (!isSafeUrlAttributeValue(key, value)) {
|
|
1714
|
+
if (typeof console !== "undefined") {
|
|
1715
|
+
console.warn(`[what] Blocked unsafe URL in "${key}" attribute: ${value}`);
|
|
1716
|
+
}
|
|
1717
|
+
el.removeAttribute(getDomAttributeName(key));
|
|
1718
|
+
return;
|
|
1719
|
+
}
|
|
1720
|
+
if (key === "class" || key === "className") {
|
|
1721
|
+
el.className = value || "";
|
|
1722
|
+
} else if (key === "dangerouslySetInnerHTML") {
|
|
1723
|
+
el.innerHTML = value?.__html ?? "";
|
|
1724
|
+
} else if (key === "innerHTML") {
|
|
1725
|
+
if (value && typeof value === "object" && "__html" in value) {
|
|
1726
|
+
el.innerHTML = value.__html ?? "";
|
|
1727
|
+
} else {
|
|
1728
|
+
if (typeof console !== "undefined" && value != null && value !== "") {
|
|
1729
|
+
console.warn(
|
|
1730
|
+
'[what] Plain string innerHTML is not allowed. Use { __html: "..." } or dangerouslySetInnerHTML={{ __html: "..." }} instead.'
|
|
1731
|
+
);
|
|
1732
|
+
}
|
|
1733
|
+
}
|
|
1734
|
+
} else if (key === "style") {
|
|
1735
|
+
if (typeof value === "string") {
|
|
1736
|
+
el.style.cssText = value;
|
|
1737
|
+
} else if (typeof value === "object") {
|
|
1738
|
+
for (const prop in value) {
|
|
1739
|
+
el.style[prop] = value[prop] ?? "";
|
|
1740
|
+
}
|
|
1741
|
+
}
|
|
1742
|
+
} else if (key.startsWith("data-") || key.startsWith("aria-")) {
|
|
1743
|
+
el.setAttribute(key, value);
|
|
1744
|
+
} else if (typeof value === "boolean") {
|
|
1745
|
+
if (value) el.setAttribute(key, "");
|
|
1746
|
+
else el.removeAttribute(key);
|
|
1747
|
+
} else if (key in el) {
|
|
1748
|
+
el[key] = value;
|
|
1749
|
+
} else {
|
|
1750
|
+
el.setAttribute(key, value);
|
|
1751
|
+
}
|
|
1752
|
+
}
|
|
1753
|
+
var delegatedEvents = /* @__PURE__ */ new Set();
|
|
1754
|
+
function delegateEvents(eventNames) {
|
|
1755
|
+
for (const name of eventNames) {
|
|
1756
|
+
if (delegatedEvents.has(name)) continue;
|
|
1757
|
+
delegatedEvents.add(name);
|
|
1758
|
+
document.addEventListener(name, (e) => {
|
|
1759
|
+
let node = e.target;
|
|
1760
|
+
const key = "$$" + name;
|
|
1761
|
+
while (node) {
|
|
1762
|
+
const handler = node[key];
|
|
1763
|
+
if (handler) {
|
|
1764
|
+
handler(e);
|
|
1765
|
+
if (e.cancelBubble) return;
|
|
1766
|
+
}
|
|
1767
|
+
node = node.parentNode;
|
|
1768
|
+
}
|
|
1769
|
+
});
|
|
1770
|
+
}
|
|
1771
|
+
}
|
|
1772
|
+
function on(el, event, handler) {
|
|
1773
|
+
el.addEventListener(event, handler);
|
|
1774
|
+
return () => el.removeEventListener(event, handler);
|
|
1775
|
+
}
|
|
1776
|
+
function classList(el, classes) {
|
|
1777
|
+
effect(() => {
|
|
1778
|
+
for (const name in classes) {
|
|
1779
|
+
const value = typeof classes[name] === "function" ? classes[name]() : classes[name];
|
|
1780
|
+
el.classList.toggle(name, !!value);
|
|
1781
|
+
}
|
|
1782
|
+
});
|
|
1783
|
+
}
|
|
1784
|
+
export {
|
|
1785
|
+
_$createComponent,
|
|
1786
|
+
_$templateImpl as _$template,
|
|
1787
|
+
template as _template,
|
|
1788
|
+
classList,
|
|
1789
|
+
delegateEvents,
|
|
1790
|
+
effect,
|
|
1791
|
+
insert,
|
|
1792
|
+
mapArray,
|
|
1793
|
+
on,
|
|
1794
|
+
setProp2 as setProp,
|
|
1795
|
+
spread,
|
|
1796
|
+
template,
|
|
1797
|
+
untrack
|
|
1798
|
+
};
|
|
1799
|
+
//# sourceMappingURL=compiler.js.map
|