@geektech/tsone 0.0.1 → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README-zh.md +405 -0
- package/README.md +288 -32
- package/dist/core/animation/TransitionGroup.d.ts +7 -0
- package/dist/core/animation/index.d.ts +2 -0
- package/dist/core/animation/list-animation-controller.d.ts +16 -0
- package/dist/core/animation/transition-group-strategy.d.ts +15 -0
- package/dist/core/animation/types.d.ts +25 -0
- package/dist/core/app.d.ts +30 -8
- package/dist/core/component/base.d.ts +18 -1
- package/dist/core/component/index.d.ts +2 -2
- package/dist/core/document.d.ts +32 -0
- package/dist/core/form.d.ts +24 -0
- package/dist/core/index.d.ts +4 -0
- package/dist/core/model.d.ts +18 -0
- package/dist/core/reactive/types.d.ts +5 -0
- package/dist/core/reactive.d.ts +5 -2
- package/dist/core/renderer/element-strategy.d.ts +25 -0
- package/dist/core/renderer/types.d.ts +6 -1
- package/dist/core/renderer.d.ts +9 -23
- package/dist/core/vnode.d.ts +56 -16
- package/dist/{index-dgv88dz4.js → index-8wjswsye.js} +6 -2
- package/dist/index-8wjswsye.js.map +10 -0
- package/dist/index-vpx80nq5.js +32 -0
- package/dist/index-vpx80nq5.js.map +10 -0
- package/dist/{index-3j2jsdpc.js → index-wv9gyjqt.js} +858 -244
- package/dist/index-wv9gyjqt.js.map +25 -0
- package/dist/index.d.ts +3 -2
- package/dist/index.js +380 -20
- package/dist/index.js.map +8 -5
- package/dist/router/index.d.ts +1 -1
- package/dist/router/index.js +6 -4
- package/dist/router/index.js.map +1 -1
- package/dist/style/StyleManager.d.ts +1 -0
- package/dist/style/index.d.ts +1 -0
- package/dist/style/index.js +6 -2
- package/dist/style/index.js.map +1 -1
- package/dist/style/sheet.d.ts +13 -0
- package/package.json +4 -14
- package/dist/index-3j2jsdpc.js.map +0 -20
- package/dist/index-dgv88dz4.js.map +0 -10
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import {
|
|
2
2
|
StyleManager
|
|
3
|
-
} from "./index-
|
|
3
|
+
} from "./index-8wjswsye.js";
|
|
4
4
|
|
|
5
5
|
// lib/core/reactive/types.ts
|
|
6
6
|
var IS_REACTIVE = Symbol("is_reactive");
|
|
7
7
|
var IS_READONLY = Symbol("is_readonly");
|
|
8
|
+
var IS_REF = Symbol("is_ref");
|
|
8
9
|
var MUTATING_ARRAY_METHODS = [
|
|
9
10
|
"push",
|
|
10
11
|
"pop",
|
|
@@ -62,7 +63,7 @@ class ReactiveSystem {
|
|
|
62
63
|
}
|
|
63
64
|
this.track(target2, key);
|
|
64
65
|
const value = Reflect.get(target2, key);
|
|
65
|
-
if (value &&
|
|
66
|
+
if (isObject(value) && !hasReactiveFlag(value, IS_READONLY)) {
|
|
66
67
|
return this.reactive(value);
|
|
67
68
|
}
|
|
68
69
|
return value;
|
|
@@ -73,7 +74,7 @@ class ReactiveSystem {
|
|
|
73
74
|
return false;
|
|
74
75
|
}
|
|
75
76
|
const oldValue = Reflect.get(target2, key);
|
|
76
|
-
if (value &&
|
|
77
|
+
if (isObject(value) && !hasReactiveFlag(value, IS_REACTIVE) && !hasReactiveFlag(value, IS_READONLY)) {
|
|
77
78
|
value = this.reactive(value);
|
|
78
79
|
}
|
|
79
80
|
const result = Reflect.set(target2, key, value);
|
|
@@ -121,6 +122,9 @@ class ReactiveSystem {
|
|
|
121
122
|
return result;
|
|
122
123
|
};
|
|
123
124
|
}
|
|
125
|
+
if (isObject(value) && !hasReactiveFlag(value, IS_READONLY)) {
|
|
126
|
+
return this.reactive(value);
|
|
127
|
+
}
|
|
124
128
|
return value;
|
|
125
129
|
},
|
|
126
130
|
set: (target2, key, value) => {
|
|
@@ -129,7 +133,7 @@ class ReactiveSystem {
|
|
|
129
133
|
return false;
|
|
130
134
|
}
|
|
131
135
|
const oldValue = Reflect.get(target2, key);
|
|
132
|
-
if (value &&
|
|
136
|
+
if (isObject(value) && !hasReactiveFlag(value, IS_REACTIVE) && !hasReactiveFlag(value, IS_READONLY)) {
|
|
133
137
|
value = this.reactive(value);
|
|
134
138
|
}
|
|
135
139
|
const result = Reflect.set(target2, key, value);
|
|
@@ -171,11 +175,14 @@ class ReactiveSystem {
|
|
|
171
175
|
}
|
|
172
176
|
const proxy = new Proxy(target, {
|
|
173
177
|
get: (target2, key) => {
|
|
174
|
-
if (key === IS_REACTIVE
|
|
178
|
+
if (key === IS_REACTIVE) {
|
|
179
|
+
return false;
|
|
180
|
+
}
|
|
181
|
+
if (key === IS_READONLY) {
|
|
175
182
|
return true;
|
|
176
183
|
}
|
|
177
184
|
const value = Reflect.get(target2, key);
|
|
178
|
-
if (
|
|
185
|
+
if (isObject(value)) {
|
|
179
186
|
return this.readonly(value);
|
|
180
187
|
}
|
|
181
188
|
return value;
|
|
@@ -193,7 +200,7 @@ class ReactiveSystem {
|
|
|
193
200
|
return proxy;
|
|
194
201
|
}
|
|
195
202
|
effect(fn, options) {
|
|
196
|
-
const { lazy = false, scheduler } = options || {};
|
|
203
|
+
const { lazy = false, scheduler, throwOnError = false } = options || {};
|
|
197
204
|
const effectFn = () => {
|
|
198
205
|
if (!effectFn.active) {
|
|
199
206
|
return fn();
|
|
@@ -204,6 +211,9 @@ class ReactiveSystem {
|
|
|
204
211
|
this.activeEffect = effectFn;
|
|
205
212
|
return fn();
|
|
206
213
|
} catch (error) {
|
|
214
|
+
if (throwOnError) {
|
|
215
|
+
throw error;
|
|
216
|
+
}
|
|
207
217
|
console.error("Effect error:", error);
|
|
208
218
|
return;
|
|
209
219
|
} finally {
|
|
@@ -310,6 +320,21 @@ function effect(fn, options) {
|
|
|
310
320
|
function computed(getter) {
|
|
311
321
|
return ReactiveSystem.getInstance().computed(getter);
|
|
312
322
|
}
|
|
323
|
+
function ref(value) {
|
|
324
|
+
const wrapper = { value };
|
|
325
|
+
Object.defineProperty(wrapper, IS_REF, {
|
|
326
|
+
configurable: false,
|
|
327
|
+
enumerable: false,
|
|
328
|
+
value: true
|
|
329
|
+
});
|
|
330
|
+
return reactive(wrapper);
|
|
331
|
+
}
|
|
332
|
+
function isRef(value) {
|
|
333
|
+
return isObject(value) && Boolean(Reflect.get(value, IS_REF));
|
|
334
|
+
}
|
|
335
|
+
function unref(value) {
|
|
336
|
+
return isRef(value) ? value.value : value;
|
|
337
|
+
}
|
|
313
338
|
function stop(effect2) {
|
|
314
339
|
ReactiveSystem.getInstance().stop(effect2);
|
|
315
340
|
}
|
|
@@ -320,40 +345,6 @@ function isReadonly(value) {
|
|
|
320
345
|
return isObject(value) && hasReactiveFlag(value, IS_READONLY);
|
|
321
346
|
}
|
|
322
347
|
|
|
323
|
-
// lib/core/renderer/props.ts
|
|
324
|
-
function isEventProp(key) {
|
|
325
|
-
return /^on[A-Z]/.test(key) || /^on[a-z]/.test(key);
|
|
326
|
-
}
|
|
327
|
-
function eventNameFromProp(key) {
|
|
328
|
-
return key.slice(2).toLowerCase();
|
|
329
|
-
}
|
|
330
|
-
function parseEventName(event) {
|
|
331
|
-
const [eventName, ...modifiers] = event.split(".");
|
|
332
|
-
return { eventName, modifiers: new Set(modifiers) };
|
|
333
|
-
}
|
|
334
|
-
function wrapEventHandler(handler, modifiers) {
|
|
335
|
-
const eventHandler = (event) => {
|
|
336
|
-
if (modifiers.has("stop")) {
|
|
337
|
-
event.stopPropagation();
|
|
338
|
-
}
|
|
339
|
-
if (modifiers.has("prevent")) {
|
|
340
|
-
event.preventDefault();
|
|
341
|
-
}
|
|
342
|
-
if (modifiers.has("self") && event.currentTarget !== event.target) {
|
|
343
|
-
return;
|
|
344
|
-
}
|
|
345
|
-
if (modifiers.has("once")) {
|
|
346
|
-
event.currentTarget.removeEventListener(event.type, eventHandler);
|
|
347
|
-
}
|
|
348
|
-
handler(event);
|
|
349
|
-
};
|
|
350
|
-
return eventHandler;
|
|
351
|
-
}
|
|
352
|
-
function setStyleValue(style, property, value) {
|
|
353
|
-
const cssProperty = property.includes("-") ? property : property.replace(/[A-Z]/g, (match) => `-${match.toLowerCase()}`);
|
|
354
|
-
style.setProperty(cssProperty, String(value));
|
|
355
|
-
}
|
|
356
|
-
|
|
357
348
|
// lib/core/vnode.ts
|
|
358
349
|
function isComponentNode(vnode) {
|
|
359
350
|
return typeof vnode === "object" && vnode !== null && "component" in vnode;
|
|
@@ -374,6 +365,55 @@ function h(tag, props, children, listeners, key, directions) {
|
|
|
374
365
|
directions
|
|
375
366
|
};
|
|
376
367
|
}
|
|
368
|
+
function Tag(tag, options = {}) {
|
|
369
|
+
return {
|
|
370
|
+
tag,
|
|
371
|
+
...options
|
|
372
|
+
};
|
|
373
|
+
}
|
|
374
|
+
function createElementFactory(tag) {
|
|
375
|
+
return (options = {}) => Tag(tag, options);
|
|
376
|
+
}
|
|
377
|
+
var Div = createElementFactory("div");
|
|
378
|
+
var Span = createElementFactory("span");
|
|
379
|
+
var P = createElementFactory("p");
|
|
380
|
+
var Button = createElementFactory("button");
|
|
381
|
+
var Input = createElementFactory("input");
|
|
382
|
+
var Section = createElementFactory("section");
|
|
383
|
+
var Main = createElementFactory("main");
|
|
384
|
+
var Header = createElementFactory("header");
|
|
385
|
+
var Footer = createElementFactory("footer");
|
|
386
|
+
var Nav = createElementFactory("nav");
|
|
387
|
+
var Article = createElementFactory("article");
|
|
388
|
+
var Aside = createElementFactory("aside");
|
|
389
|
+
var H1 = createElementFactory("h1");
|
|
390
|
+
var H2 = createElementFactory("h2");
|
|
391
|
+
var H3 = createElementFactory("h3");
|
|
392
|
+
var H4 = createElementFactory("h4");
|
|
393
|
+
var H5 = createElementFactory("h5");
|
|
394
|
+
var H6 = createElementFactory("h6");
|
|
395
|
+
var Strong = createElementFactory("strong");
|
|
396
|
+
var Em = createElementFactory("em");
|
|
397
|
+
var Small = createElementFactory("small");
|
|
398
|
+
var Pre = createElementFactory("pre");
|
|
399
|
+
var Code = createElementFactory("code");
|
|
400
|
+
var Blockquote = createElementFactory("blockquote");
|
|
401
|
+
var Ul = createElementFactory("ul");
|
|
402
|
+
var Ol = createElementFactory("ol");
|
|
403
|
+
var Li = createElementFactory("li");
|
|
404
|
+
var A = createElementFactory("a");
|
|
405
|
+
var Img = createElementFactory("img");
|
|
406
|
+
var Form = createElementFactory("form");
|
|
407
|
+
var Label = createElementFactory("label");
|
|
408
|
+
var Textarea = createElementFactory("textarea");
|
|
409
|
+
var Select = createElementFactory("select");
|
|
410
|
+
var Option = createElementFactory("option");
|
|
411
|
+
var Table = createElementFactory("table");
|
|
412
|
+
var Thead = createElementFactory("thead");
|
|
413
|
+
var Tbody = createElementFactory("tbody");
|
|
414
|
+
var Tr = createElementFactory("tr");
|
|
415
|
+
var Th = createElementFactory("th");
|
|
416
|
+
var Td = createElementFactory("td");
|
|
377
417
|
function createComponent(componentClass, props, children, key, directions) {
|
|
378
418
|
return {
|
|
379
419
|
component: componentClass,
|
|
@@ -391,166 +431,236 @@ function slot(name, key, directions) {
|
|
|
391
431
|
directions
|
|
392
432
|
};
|
|
393
433
|
}
|
|
434
|
+
function each(items, render, key) {
|
|
435
|
+
return items.map((item, index) => {
|
|
436
|
+
const vnode = render(item, index);
|
|
437
|
+
if (typeof vnode === "string") {
|
|
438
|
+
throw new Error("each render callback must return a VNode");
|
|
439
|
+
}
|
|
440
|
+
return { ...vnode, key: key(item, index) };
|
|
441
|
+
});
|
|
442
|
+
}
|
|
394
443
|
|
|
395
|
-
// lib/core/
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
new TextRenderStrategy,
|
|
401
|
-
new ComponentRenderStrategy,
|
|
402
|
-
new SlotRenderStrategy,
|
|
403
|
-
new ElementRenderStrategy
|
|
404
|
-
];
|
|
444
|
+
// lib/core/model.ts
|
|
445
|
+
function pathSegments(path) {
|
|
446
|
+
const segments = path.split(".");
|
|
447
|
+
if (path.length === 0 || segments.some((segment) => segment.length === 0 || segment === "__proto__" || segment === "prototype" || segment === "constructor")) {
|
|
448
|
+
throw new Error(`Invalid model path "${path}"`);
|
|
405
449
|
}
|
|
406
|
-
|
|
407
|
-
|
|
450
|
+
return segments;
|
|
451
|
+
}
|
|
452
|
+
function isRecord(value) {
|
|
453
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
454
|
+
}
|
|
455
|
+
function hasOwn(value, key) {
|
|
456
|
+
return Object.prototype.hasOwnProperty.call(value, key);
|
|
457
|
+
}
|
|
458
|
+
function modelPath(binding) {
|
|
459
|
+
return typeof binding === "string" ? binding : binding.path;
|
|
460
|
+
}
|
|
461
|
+
function getModelValue(state, path) {
|
|
462
|
+
let value = state;
|
|
463
|
+
for (const segment of pathSegments(path)) {
|
|
464
|
+
if (!isRecord(value)) {
|
|
465
|
+
throw new Error(`Invalid model path "${path}"`);
|
|
466
|
+
}
|
|
467
|
+
if (!hasOwn(value, segment)) {
|
|
468
|
+
if (segment in value) {
|
|
469
|
+
throw new Error(`Invalid model path "${path}"`);
|
|
470
|
+
}
|
|
471
|
+
return;
|
|
472
|
+
}
|
|
473
|
+
value = value[segment];
|
|
408
474
|
}
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
475
|
+
return value;
|
|
476
|
+
}
|
|
477
|
+
function setModelValue(state, path, value) {
|
|
478
|
+
const segments = pathSegments(path);
|
|
479
|
+
let target = state;
|
|
480
|
+
for (const segment of segments.slice(0, -1)) {
|
|
481
|
+
if (!hasOwn(target, segment)) {
|
|
482
|
+
if (segment in target) {
|
|
483
|
+
throw new Error(`Invalid model path "${path}"`);
|
|
484
|
+
}
|
|
485
|
+
target[segment] = {};
|
|
486
|
+
} else if (!isRecord(target[segment])) {
|
|
487
|
+
throw new Error(`Invalid model path "${path}"`);
|
|
417
488
|
}
|
|
418
|
-
|
|
489
|
+
const nextTarget = target[segment];
|
|
490
|
+
if (!isRecord(nextTarget)) {
|
|
491
|
+
throw new Error(`Invalid model path "${path}"`);
|
|
492
|
+
}
|
|
493
|
+
target = nextTarget;
|
|
419
494
|
}
|
|
420
|
-
|
|
421
|
-
|
|
495
|
+
const lastSegment = segments[segments.length - 1];
|
|
496
|
+
target[lastSegment] = value;
|
|
497
|
+
}
|
|
498
|
+
function displayValue(binding, value) {
|
|
499
|
+
if (typeof binding !== "string" && binding.format) {
|
|
500
|
+
return binding.format(value);
|
|
422
501
|
}
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
return strategy;
|
|
502
|
+
return value === undefined || value === null ? "" : String(value);
|
|
503
|
+
}
|
|
504
|
+
function toModelValue(binding, value) {
|
|
505
|
+
if (typeof binding !== "string" && binding.parse) {
|
|
506
|
+
return binding.parse(value);
|
|
429
507
|
}
|
|
508
|
+
return value;
|
|
430
509
|
}
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
510
|
+
function syncControl(element, binding, value) {
|
|
511
|
+
if (element instanceof HTMLInputElement) {
|
|
512
|
+
if (element.type === "checkbox") {
|
|
513
|
+
element.checked = Array.isArray(value) ? value.some((item) => String(item) === element.value) : Boolean(value);
|
|
514
|
+
return;
|
|
515
|
+
}
|
|
516
|
+
if (element.type === "radio") {
|
|
517
|
+
element.checked = value === element.value;
|
|
518
|
+
return;
|
|
519
|
+
}
|
|
520
|
+
element.value = displayValue(binding, value);
|
|
521
|
+
return;
|
|
435
522
|
}
|
|
436
|
-
|
|
437
|
-
|
|
523
|
+
if (element instanceof HTMLTextAreaElement) {
|
|
524
|
+
element.value = displayValue(binding, value);
|
|
525
|
+
return;
|
|
438
526
|
}
|
|
439
|
-
|
|
440
|
-
if (
|
|
441
|
-
|
|
527
|
+
if (element instanceof HTMLSelectElement) {
|
|
528
|
+
if (element.multiple) {
|
|
529
|
+
const selected = Array.isArray(value) ? new Set(value.map(String)) : new Set;
|
|
530
|
+
for (let index = 0;index < element.options.length; index += 1) {
|
|
531
|
+
const option = element.options.item(index);
|
|
532
|
+
if (!option) {
|
|
533
|
+
continue;
|
|
534
|
+
}
|
|
535
|
+
option.selected = selected.has(option.value);
|
|
536
|
+
}
|
|
537
|
+
return;
|
|
442
538
|
}
|
|
443
|
-
|
|
444
|
-
currentNode.parentNode?.replaceChild(nextNode, currentNode);
|
|
445
|
-
return nextNode;
|
|
539
|
+
element.value = displayValue(binding, value);
|
|
446
540
|
}
|
|
447
|
-
unmount() {}
|
|
448
541
|
}
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
const instance = new ComponentClass(this.createProps(vnode));
|
|
458
|
-
if (context.appContext && instance.setAppContext) {
|
|
459
|
-
instance.setAppContext(context.appContext);
|
|
542
|
+
function controlValue(element, currentValue) {
|
|
543
|
+
if (element instanceof HTMLInputElement) {
|
|
544
|
+
if (element.type === "checkbox") {
|
|
545
|
+
if (Array.isArray(currentValue)) {
|
|
546
|
+
const values = currentValue.filter((value) => String(value) !== element.value);
|
|
547
|
+
return element.checked ? [...values, element.value] : values;
|
|
548
|
+
}
|
|
549
|
+
return element.checked;
|
|
460
550
|
}
|
|
461
|
-
if (
|
|
462
|
-
|
|
463
|
-
instance.on(eventName, listener);
|
|
464
|
-
});
|
|
551
|
+
if (element.type === "radio") {
|
|
552
|
+
return element.checked ? element.value : currentValue;
|
|
465
553
|
}
|
|
466
|
-
|
|
467
|
-
const node = instance.mountToNode();
|
|
468
|
-
this.instances.set(node, instance);
|
|
469
|
-
return node;
|
|
554
|
+
return element.value;
|
|
470
555
|
}
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
if (instance && oldVNode.component === newVNode.component) {
|
|
474
|
-
instance.setProps(this.createProps(newVNode));
|
|
475
|
-
instance.update();
|
|
476
|
-
const nextNode2 = instance.getElement() ?? currentNode;
|
|
477
|
-
this.instances.set(nextNode2, instance);
|
|
478
|
-
return nextNode2;
|
|
479
|
-
}
|
|
480
|
-
const nextNode = this.mount(newVNode, context);
|
|
481
|
-
currentNode.parentNode?.replaceChild(nextNode, currentNode);
|
|
482
|
-
this.unmount(oldVNode, currentNode);
|
|
483
|
-
return nextNode;
|
|
556
|
+
if (element instanceof HTMLTextAreaElement) {
|
|
557
|
+
return element.value;
|
|
484
558
|
}
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
instance.unmount();
|
|
489
|
-
this.instances.delete(currentNode);
|
|
559
|
+
if (element instanceof HTMLSelectElement) {
|
|
560
|
+
if (!element.multiple) {
|
|
561
|
+
return element.value;
|
|
490
562
|
}
|
|
563
|
+
const values = [];
|
|
564
|
+
for (let index = 0;index < element.selectedOptions.length; index += 1) {
|
|
565
|
+
const option = element.selectedOptions.item(index);
|
|
566
|
+
if (option) {
|
|
567
|
+
values.push(option.value);
|
|
568
|
+
}
|
|
569
|
+
}
|
|
570
|
+
return values;
|
|
491
571
|
}
|
|
492
|
-
|
|
493
|
-
return {
|
|
494
|
-
...vnode.props ?? {},
|
|
495
|
-
children: vnode.children ?? []
|
|
496
|
-
};
|
|
497
|
-
}
|
|
572
|
+
return;
|
|
498
573
|
}
|
|
499
574
|
|
|
500
|
-
class
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
mount(vnode, context) {
|
|
506
|
-
const slotContainer = document.createElement("div");
|
|
507
|
-
slotContainer.setAttribute("data-slot", vnode.props.name);
|
|
508
|
-
this.mountSlotChildren(slotContainer, this.resolveChildren(vnode, context), context);
|
|
509
|
-
return slotContainer;
|
|
510
|
-
}
|
|
511
|
-
patch(oldVNode, newVNode, currentNode, context) {
|
|
512
|
-
if (currentNode instanceof HTMLElement) {
|
|
513
|
-
currentNode.setAttribute("data-slot", newVNode.props.name);
|
|
514
|
-
this.replaceSlotChildren(currentNode, oldVNode, newVNode, context);
|
|
575
|
+
class ModelBindingController {
|
|
576
|
+
bindings = new WeakMap;
|
|
577
|
+
bind(element, binding, state) {
|
|
578
|
+
if (!this.isSupportedControl(element)) {
|
|
579
|
+
return;
|
|
515
580
|
}
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
unmount(_vnode, currentNode, context) {
|
|
519
|
-
if (!(currentNode instanceof HTMLElement)) {
|
|
581
|
+
const existing = this.bindings.get(element);
|
|
582
|
+
if (existing && this.sameBinding(existing, binding)) {
|
|
520
583
|
return;
|
|
521
584
|
}
|
|
522
|
-
this.
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
585
|
+
this.cleanup(element);
|
|
586
|
+
const path = modelPath(binding);
|
|
587
|
+
const sync = () => syncControl(element, binding, getModelValue(state, path));
|
|
588
|
+
const eventName = element instanceof HTMLTextAreaElement || element instanceof HTMLInputElement && !["checkbox", "radio"].includes(element.type) ? "input" : "change";
|
|
589
|
+
const listener = () => {
|
|
590
|
+
const currentValue = getModelValue(state, path);
|
|
591
|
+
setModelValue(state, path, toModelValue(binding, controlValue(element, currentValue)));
|
|
592
|
+
};
|
|
593
|
+
element.addEventListener(eventName, listener);
|
|
594
|
+
const effectRef = effect(sync);
|
|
595
|
+
this.bindings.set(element, {
|
|
596
|
+
binding,
|
|
597
|
+
path,
|
|
598
|
+
parse: typeof binding === "string" ? undefined : binding.parse,
|
|
599
|
+
format: typeof binding === "string" ? undefined : binding.format,
|
|
600
|
+
eventName,
|
|
601
|
+
listener,
|
|
602
|
+
effect: effectRef
|
|
603
|
+
});
|
|
527
604
|
}
|
|
528
|
-
|
|
529
|
-
this.
|
|
530
|
-
|
|
531
|
-
|
|
605
|
+
cleanup(element) {
|
|
606
|
+
const existing = this.bindings.get(element);
|
|
607
|
+
if (!existing) {
|
|
608
|
+
return;
|
|
609
|
+
}
|
|
610
|
+
element.removeEventListener(existing.eventName, existing.listener);
|
|
611
|
+
stop(existing.effect);
|
|
612
|
+
this.bindings.delete(element);
|
|
532
613
|
}
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
element.appendChild(context.renderer.mount(child, context));
|
|
536
|
-
});
|
|
537
|
-
this.renderedChildren.set(element, children);
|
|
614
|
+
isSupportedControl(element) {
|
|
615
|
+
return element instanceof HTMLInputElement || element instanceof HTMLTextAreaElement || element instanceof HTMLSelectElement;
|
|
538
616
|
}
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
context.renderer.unmount(child, childNode, context);
|
|
545
|
-
}
|
|
546
|
-
});
|
|
617
|
+
sameBinding(record, binding) {
|
|
618
|
+
if (typeof record.binding === "string" || typeof binding === "string") {
|
|
619
|
+
return record.binding === binding;
|
|
620
|
+
}
|
|
621
|
+
return record.path === binding.path && record.parse === binding.parse && record.format === binding.format;
|
|
547
622
|
}
|
|
548
623
|
}
|
|
549
624
|
|
|
625
|
+
// lib/core/renderer/props.ts
|
|
626
|
+
function isEventProp(key) {
|
|
627
|
+
return /^on[A-Z]/.test(key) || /^on[a-z]/.test(key);
|
|
628
|
+
}
|
|
629
|
+
function eventNameFromProp(key) {
|
|
630
|
+
return key.slice(2).toLowerCase();
|
|
631
|
+
}
|
|
632
|
+
function parseEventName(event) {
|
|
633
|
+
const [eventName, ...modifiers] = event.split(".");
|
|
634
|
+
return { eventName, modifiers: new Set(modifiers) };
|
|
635
|
+
}
|
|
636
|
+
function wrapEventHandler(handler, modifiers) {
|
|
637
|
+
const eventHandler = (event) => {
|
|
638
|
+
if (modifiers.has("stop")) {
|
|
639
|
+
event.stopPropagation();
|
|
640
|
+
}
|
|
641
|
+
if (modifiers.has("prevent")) {
|
|
642
|
+
event.preventDefault();
|
|
643
|
+
}
|
|
644
|
+
if (modifiers.has("self") && event.currentTarget !== event.target) {
|
|
645
|
+
return;
|
|
646
|
+
}
|
|
647
|
+
if (modifiers.has("once")) {
|
|
648
|
+
event.currentTarget.removeEventListener(event.type, eventHandler);
|
|
649
|
+
}
|
|
650
|
+
handler(event);
|
|
651
|
+
};
|
|
652
|
+
return eventHandler;
|
|
653
|
+
}
|
|
654
|
+
function setStyleValue(style, property, value) {
|
|
655
|
+
const cssProperty = property.includes("-") ? property : property.replace(/[A-Z]/g, (match) => `-${match.toLowerCase()}`);
|
|
656
|
+
style.setProperty(cssProperty, String(value));
|
|
657
|
+
}
|
|
658
|
+
|
|
659
|
+
// lib/core/renderer/element-strategy.ts
|
|
550
660
|
class ElementRenderStrategy {
|
|
551
661
|
listeners = new WeakMap;
|
|
552
662
|
effects = new WeakMap;
|
|
553
|
-
modelBindings = new
|
|
663
|
+
modelBindings = new ModelBindingController;
|
|
554
664
|
matches(vnode) {
|
|
555
665
|
return typeof vnode === "object" && vnode !== null && isHTMLNode(vnode);
|
|
556
666
|
}
|
|
@@ -560,11 +670,9 @@ class ElementRenderStrategy {
|
|
|
560
670
|
}
|
|
561
671
|
const element = document.createElement(vnode.tag);
|
|
562
672
|
this.applyProps(element, {}, vnode.props ?? {}, context);
|
|
563
|
-
this.applyDirections(element, undefined, vnode.directions, context);
|
|
564
673
|
this.updateListeners(element, {}, this.collectListeners(vnode));
|
|
565
|
-
(vnode
|
|
566
|
-
|
|
567
|
-
});
|
|
674
|
+
this.mountChildren(element, vnode, context);
|
|
675
|
+
this.applyDirections(element, undefined, vnode.directions, context);
|
|
568
676
|
return element;
|
|
569
677
|
}
|
|
570
678
|
patch(oldVNode, newVNode, currentNode, context) {
|
|
@@ -584,9 +692,9 @@ class ElementRenderStrategy {
|
|
|
584
692
|
return nextNode;
|
|
585
693
|
}
|
|
586
694
|
this.applyProps(currentNode, oldVNode.props ?? {}, newVNode.props ?? {}, context);
|
|
587
|
-
this.applyDirections(currentNode, oldVNode.directions, newVNode.directions, context);
|
|
588
695
|
this.updateListeners(currentNode, this.collectListeners(oldVNode), this.collectListeners(newVNode));
|
|
589
|
-
this.updateChildren(currentNode, oldVNode
|
|
696
|
+
this.updateChildren(currentNode, oldVNode, newVNode, context);
|
|
697
|
+
this.applyDirections(currentNode, oldVNode.directions, newVNode.directions, context);
|
|
590
698
|
return currentNode;
|
|
591
699
|
}
|
|
592
700
|
unmount(vnode, currentNode, context) {
|
|
@@ -599,9 +707,20 @@ class ElementRenderStrategy {
|
|
|
599
707
|
currentNode.removeEventListener(eventName, listener);
|
|
600
708
|
});
|
|
601
709
|
this.listeners.delete(currentNode);
|
|
602
|
-
this.modelBindings.
|
|
710
|
+
this.modelBindings.cleanup(currentNode);
|
|
711
|
+
this.unmountChildren(currentNode, vnode, context);
|
|
712
|
+
}
|
|
713
|
+
mountChildren(element, vnode, context) {
|
|
714
|
+
(vnode.children ?? []).forEach((child) => {
|
|
715
|
+
element.appendChild(context.renderer.mount(child, context));
|
|
716
|
+
});
|
|
717
|
+
}
|
|
718
|
+
updateChildren(element, oldVNode, newVNode, context) {
|
|
719
|
+
this.updateOrdinaryChildren(element, oldVNode.children ?? [], newVNode.children ?? [], context);
|
|
720
|
+
}
|
|
721
|
+
unmountChildren(element, vnode, context) {
|
|
603
722
|
(vnode.children ?? []).forEach((child, index) => {
|
|
604
|
-
const childNode =
|
|
723
|
+
const childNode = element.childNodes[index];
|
|
605
724
|
if (childNode) {
|
|
606
725
|
context.renderer.unmount(child, childNode, context);
|
|
607
726
|
}
|
|
@@ -656,12 +775,16 @@ class ElementRenderStrategy {
|
|
|
656
775
|
} else if (oldDirections && "show" in oldDirections) {
|
|
657
776
|
element.style.display = "";
|
|
658
777
|
}
|
|
659
|
-
if (newDirections?.model) {
|
|
660
|
-
this.
|
|
778
|
+
if (!newDirections?.model) {
|
|
779
|
+
this.modelBindings.cleanup(element);
|
|
780
|
+
return;
|
|
661
781
|
}
|
|
782
|
+
this.modelBindings.bind(element, newDirections.model, context.templateEngine.state);
|
|
662
783
|
}
|
|
663
|
-
|
|
664
|
-
|
|
784
|
+
updateOrdinaryChildren(element, oldChildren, newChildren, context) {
|
|
785
|
+
this.assertNoDuplicateKeys(oldChildren);
|
|
786
|
+
this.assertNoDuplicateKeys(newChildren);
|
|
787
|
+
if (this.hasOnlyKeyedChildren(oldChildren, newChildren)) {
|
|
665
788
|
this.updateKeyedChildren(element, oldChildren, newChildren, context);
|
|
666
789
|
return;
|
|
667
790
|
}
|
|
@@ -730,13 +853,26 @@ class ElementRenderStrategy {
|
|
|
730
853
|
}
|
|
731
854
|
});
|
|
732
855
|
}
|
|
733
|
-
|
|
734
|
-
return [...oldChildren, ...newChildren].
|
|
856
|
+
hasOnlyKeyedChildren(oldChildren, newChildren) {
|
|
857
|
+
return [...oldChildren, ...newChildren].every((child) => this.getVNodeKey(child) !== undefined);
|
|
735
858
|
}
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
859
|
+
assertNoDuplicateKeys(children) {
|
|
860
|
+
const keys = new Set;
|
|
861
|
+
children.forEach((child) => {
|
|
862
|
+
const key = this.getVNodeKey(child);
|
|
863
|
+
if (key === undefined) {
|
|
864
|
+
return;
|
|
865
|
+
}
|
|
866
|
+
if (keys.has(key)) {
|
|
867
|
+
throw new Error(`Duplicate key "${key}"`);
|
|
868
|
+
}
|
|
869
|
+
keys.add(key);
|
|
870
|
+
});
|
|
871
|
+
}
|
|
872
|
+
getVNodeKey(vnode) {
|
|
873
|
+
if (typeof vnode === "string") {
|
|
874
|
+
return;
|
|
875
|
+
}
|
|
740
876
|
return vnode.key;
|
|
741
877
|
}
|
|
742
878
|
collectListeners(vnode) {
|
|
@@ -780,59 +916,481 @@ class ElementRenderStrategy {
|
|
|
780
916
|
});
|
|
781
917
|
this.trackEffect(element, effectRef);
|
|
782
918
|
}
|
|
783
|
-
|
|
784
|
-
|
|
919
|
+
trackEffect(element, effectRef) {
|
|
920
|
+
const effects = this.effects.get(element) ?? new Set;
|
|
921
|
+
effects.add(effectRef);
|
|
922
|
+
this.effects.set(element, effects);
|
|
923
|
+
}
|
|
924
|
+
}
|
|
925
|
+
|
|
926
|
+
// lib/core/animation/list-animation-controller.ts
|
|
927
|
+
var ENTER_KEYFRAMES = {
|
|
928
|
+
fade: [{ opacity: 0 }, { opacity: 1 }],
|
|
929
|
+
"slide-up": [
|
|
930
|
+
{ opacity: 0, transform: "translateY(12px)" },
|
|
931
|
+
{ opacity: 1, transform: "translateY(0)" }
|
|
932
|
+
],
|
|
933
|
+
"slide-down": [
|
|
934
|
+
{ opacity: 0, transform: "translateY(-12px)" },
|
|
935
|
+
{ opacity: 1, transform: "translateY(0)" }
|
|
936
|
+
],
|
|
937
|
+
"slide-left": [
|
|
938
|
+
{ opacity: 0, transform: "translateX(12px)" },
|
|
939
|
+
{ opacity: 1, transform: "translateX(0)" }
|
|
940
|
+
],
|
|
941
|
+
"slide-right": [
|
|
942
|
+
{ opacity: 0, transform: "translateX(-12px)" },
|
|
943
|
+
{ opacity: 1, transform: "translateX(0)" }
|
|
944
|
+
],
|
|
945
|
+
scale: [
|
|
946
|
+
{ opacity: 0, transform: "scale(0.95)" },
|
|
947
|
+
{ opacity: 1, transform: "scale(1)" }
|
|
948
|
+
]
|
|
949
|
+
};
|
|
950
|
+
|
|
951
|
+
class ListAnimationController {
|
|
952
|
+
runs = new WeakMap;
|
|
953
|
+
playEnter(element, options) {
|
|
954
|
+
return this.play(element, options, "enter");
|
|
955
|
+
}
|
|
956
|
+
playExit(element, options) {
|
|
957
|
+
return this.play(element, options, "exit");
|
|
958
|
+
}
|
|
959
|
+
cancel(element) {
|
|
960
|
+
const current = this.runs.get(element);
|
|
961
|
+
if (!current) {
|
|
785
962
|
return;
|
|
786
963
|
}
|
|
787
|
-
|
|
788
|
-
|
|
964
|
+
this.runs.delete(element);
|
|
965
|
+
current.animation.cancel();
|
|
966
|
+
}
|
|
967
|
+
play(element, transition, phase) {
|
|
968
|
+
this.cancel(element);
|
|
969
|
+
if (!this.canAnimate(element)) {
|
|
970
|
+
return null;
|
|
789
971
|
}
|
|
790
|
-
|
|
791
|
-
const
|
|
792
|
-
|
|
793
|
-
|
|
972
|
+
const enterKeyframes = ENTER_KEYFRAMES[transition.type];
|
|
973
|
+
const keyframes = phase === "enter" ? [...enterKeyframes] : [...enterKeyframes].reverse();
|
|
974
|
+
const options = {
|
|
975
|
+
duration: transition.duration,
|
|
976
|
+
easing: "ease",
|
|
977
|
+
fill: "both"
|
|
978
|
+
};
|
|
979
|
+
const animation = element.animate(keyframes, options);
|
|
980
|
+
const token = Symbol("list-animation");
|
|
981
|
+
const finished = animation.finished.then(() => "finished", () => "cancelled");
|
|
982
|
+
const run = {
|
|
983
|
+
animation,
|
|
984
|
+
token,
|
|
985
|
+
keyframes,
|
|
986
|
+
options,
|
|
987
|
+
finished
|
|
794
988
|
};
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
989
|
+
this.runs.set(element, run);
|
|
990
|
+
finished.then((result) => {
|
|
991
|
+
if (this.runs.get(element)?.token !== token) {
|
|
992
|
+
return;
|
|
993
|
+
}
|
|
994
|
+
this.runs.delete(element);
|
|
995
|
+
if (phase === "enter" && result === "finished") {
|
|
996
|
+
animation.cancel();
|
|
997
|
+
}
|
|
998
|
+
});
|
|
999
|
+
return run;
|
|
1000
|
+
}
|
|
1001
|
+
canAnimate(element) {
|
|
1002
|
+
const reduced = typeof window !== "undefined" && typeof window.matchMedia === "function" && window.matchMedia("(prefers-reduced-motion: reduce)").matches;
|
|
1003
|
+
return !reduced && typeof element.animate === "function";
|
|
1004
|
+
}
|
|
1005
|
+
}
|
|
1006
|
+
|
|
1007
|
+
// lib/core/animation/types.ts
|
|
1008
|
+
var TRANSITION_ANIMATION_TYPES = [
|
|
1009
|
+
"fade",
|
|
1010
|
+
"slide-up",
|
|
1011
|
+
"slide-down",
|
|
1012
|
+
"slide-left",
|
|
1013
|
+
"slide-right",
|
|
1014
|
+
"scale"
|
|
1015
|
+
];
|
|
1016
|
+
function normalizeTransitionGroupProps(props) {
|
|
1017
|
+
const tag = (props.tag ?? "div").trim();
|
|
1018
|
+
const type = props.type ?? "fade";
|
|
1019
|
+
const duration = props.duration ?? 300;
|
|
1020
|
+
if (!tag) {
|
|
1021
|
+
throw new Error("TransitionGroup tag must not be empty");
|
|
1022
|
+
}
|
|
1023
|
+
if (!TRANSITION_ANIMATION_TYPES.includes(type)) {
|
|
1024
|
+
throw new Error(`Unknown TransitionGroup animation type "${type}"`);
|
|
1025
|
+
}
|
|
1026
|
+
if (!Number.isFinite(duration) || duration < 0) {
|
|
1027
|
+
throw new Error("TransitionGroup duration must be a non-negative finite number");
|
|
1028
|
+
}
|
|
1029
|
+
return { tag, type, duration };
|
|
1030
|
+
}
|
|
1031
|
+
function validateTransitionGroupChildren(children) {
|
|
1032
|
+
const keys = new Set;
|
|
1033
|
+
return children.map((child) => {
|
|
1034
|
+
if (typeof child === "string" || child.key === undefined || keys.has(child.key)) {
|
|
1035
|
+
throw new Error("TransitionGroup children must have unique keys");
|
|
1036
|
+
}
|
|
1037
|
+
keys.add(child.key);
|
|
1038
|
+
return child;
|
|
1039
|
+
});
|
|
1040
|
+
}
|
|
1041
|
+
function isTransitionGroupNode(vnode) {
|
|
1042
|
+
return typeof vnode === "object" && vnode !== null && "transitionGroup" in vnode && isHTMLNode(vnode);
|
|
1043
|
+
}
|
|
1044
|
+
|
|
1045
|
+
// lib/core/animation/transition-group-strategy.ts
|
|
1046
|
+
class TransitionGroupRenderStrategy extends ElementRenderStrategy {
|
|
1047
|
+
entries = new WeakMap;
|
|
1048
|
+
animations = new ListAnimationController;
|
|
1049
|
+
matches(vnode) {
|
|
1050
|
+
return isTransitionGroupNode(vnode);
|
|
1051
|
+
}
|
|
1052
|
+
mountChildren(element, groupVNode, context) {
|
|
1053
|
+
const keyedChildren = validateTransitionGroupChildren(groupVNode.children ?? []);
|
|
1054
|
+
const entries = new Map;
|
|
1055
|
+
keyedChildren.forEach((childVNode) => {
|
|
1056
|
+
const node = context.renderer.mount(childVNode, context);
|
|
1057
|
+
element.appendChild(node);
|
|
1058
|
+
const entry = {
|
|
1059
|
+
key: childVNode.key,
|
|
1060
|
+
vnode: childVNode,
|
|
1061
|
+
node,
|
|
1062
|
+
status: "active"
|
|
1063
|
+
};
|
|
1064
|
+
entries.set(entry.key, entry);
|
|
1065
|
+
this.playEnter(entry, node, groupVNode.transitionGroup);
|
|
1066
|
+
});
|
|
1067
|
+
this.entries.set(element, entries);
|
|
1068
|
+
}
|
|
1069
|
+
updateChildren(element, _oldVNode, newVNode, context) {
|
|
1070
|
+
const entries = this.entries.get(element) ?? new Map;
|
|
1071
|
+
const nextChildren = validateTransitionGroupChildren(newVNode.children ?? []);
|
|
1072
|
+
const nextKeys = new Set(nextChildren.map((child) => child.key));
|
|
1073
|
+
const ordered = [];
|
|
1074
|
+
nextChildren.forEach((childVNode) => {
|
|
1075
|
+
const key = childVNode.key;
|
|
1076
|
+
const current = entries.get(key);
|
|
1077
|
+
if (current) {
|
|
1078
|
+
const wasExiting = current.status === "exiting";
|
|
1079
|
+
if (wasExiting && current.node instanceof HTMLElement) {
|
|
1080
|
+
this.animations.cancel(current.node);
|
|
802
1081
|
}
|
|
803
|
-
|
|
1082
|
+
current.status = "active";
|
|
1083
|
+
current.animationToken = undefined;
|
|
1084
|
+
current.node = context.renderer.patch(current.vnode, childVNode, current.node, context);
|
|
1085
|
+
current.vnode = childVNode;
|
|
1086
|
+
ordered.push(current);
|
|
1087
|
+
if (wasExiting) {
|
|
1088
|
+
this.playEnter(current, current.node, newVNode.transitionGroup);
|
|
1089
|
+
}
|
|
1090
|
+
return;
|
|
804
1091
|
}
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
element.value = nextValue;
|
|
1092
|
+
const node = context.renderer.mount(childVNode, context);
|
|
1093
|
+
const entry = {
|
|
1094
|
+
key,
|
|
1095
|
+
vnode: childVNode,
|
|
1096
|
+
node,
|
|
1097
|
+
status: "active"
|
|
1098
|
+
};
|
|
1099
|
+
entries.set(key, entry);
|
|
1100
|
+
ordered.push(entry);
|
|
1101
|
+
this.playEnter(entry, node, newVNode.transitionGroup);
|
|
1102
|
+
});
|
|
1103
|
+
entries.forEach((entry, key) => {
|
|
1104
|
+
if (nextKeys.has(key) || entry.status !== "active") {
|
|
1105
|
+
return;
|
|
820
1106
|
}
|
|
1107
|
+
this.startExit(element, entry, newVNode.transitionGroup, context);
|
|
821
1108
|
});
|
|
822
|
-
this.
|
|
1109
|
+
this.placeActiveEntries(element, ordered);
|
|
1110
|
+
this.entries.set(element, entries);
|
|
823
1111
|
}
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
1112
|
+
unmountChildren(element, vnode, context) {
|
|
1113
|
+
const entries = this.entries.get(element);
|
|
1114
|
+
if (!entries) {
|
|
1115
|
+
super.unmountChildren(element, vnode, context);
|
|
1116
|
+
return;
|
|
1117
|
+
}
|
|
1118
|
+
entries.forEach((entry) => {
|
|
1119
|
+
if (entry.node instanceof HTMLElement) {
|
|
1120
|
+
this.animations.cancel(entry.node);
|
|
1121
|
+
}
|
|
1122
|
+
context.renderer.unmount(entry.vnode, entry.node, context);
|
|
1123
|
+
if (entry.node.parentNode === element) {
|
|
1124
|
+
element.removeChild(entry.node);
|
|
1125
|
+
}
|
|
1126
|
+
});
|
|
1127
|
+
entries.clear();
|
|
1128
|
+
this.entries.delete(element);
|
|
1129
|
+
}
|
|
1130
|
+
playEnter(entry, node, options) {
|
|
1131
|
+
if (!(node instanceof HTMLElement)) {
|
|
1132
|
+
return;
|
|
1133
|
+
}
|
|
1134
|
+
const run = this.animations.playEnter(node, options);
|
|
1135
|
+
entry.animationToken = run?.token;
|
|
1136
|
+
}
|
|
1137
|
+
startExit(wrapper, entry, options, context) {
|
|
1138
|
+
entry.status = "exiting";
|
|
1139
|
+
const run = entry.node instanceof HTMLElement ? this.animations.playExit(entry.node, options) : null;
|
|
1140
|
+
if (!run) {
|
|
1141
|
+
this.finishExit(wrapper, entry, context);
|
|
1142
|
+
return;
|
|
1143
|
+
}
|
|
1144
|
+
entry.animationToken = run.token;
|
|
1145
|
+
run.finished.then((result) => {
|
|
1146
|
+
if (result === "finished" && entry.status === "exiting" && entry.animationToken === run.token) {
|
|
1147
|
+
this.finishExit(wrapper, entry, context);
|
|
1148
|
+
}
|
|
1149
|
+
});
|
|
1150
|
+
}
|
|
1151
|
+
finishExit(wrapper, entry, context) {
|
|
1152
|
+
const entries = this.entries.get(wrapper);
|
|
1153
|
+
if (entries?.get(entry.key) !== entry) {
|
|
1154
|
+
return;
|
|
1155
|
+
}
|
|
1156
|
+
context.renderer.unmount(entry.vnode, entry.node, context);
|
|
1157
|
+
if (entry.node.parentNode === wrapper) {
|
|
1158
|
+
wrapper.removeChild(entry.node);
|
|
1159
|
+
}
|
|
1160
|
+
entries.delete(entry.key);
|
|
1161
|
+
}
|
|
1162
|
+
placeActiveEntries(wrapper, ordered) {
|
|
1163
|
+
let reference = null;
|
|
1164
|
+
for (let index = ordered.length - 1;index >= 0; index -= 1) {
|
|
1165
|
+
wrapper.insertBefore(ordered[index].node, reference);
|
|
1166
|
+
reference = ordered[index].node;
|
|
1167
|
+
}
|
|
1168
|
+
}
|
|
1169
|
+
}
|
|
1170
|
+
|
|
1171
|
+
// lib/core/renderer.ts
|
|
1172
|
+
class RendererContext {
|
|
1173
|
+
strategies;
|
|
1174
|
+
constructor() {
|
|
1175
|
+
this.strategies = [
|
|
1176
|
+
new TextRenderStrategy,
|
|
1177
|
+
new ComponentRenderStrategy,
|
|
1178
|
+
new SlotRenderStrategy,
|
|
1179
|
+
new TransitionGroupRenderStrategy,
|
|
1180
|
+
new ElementRenderStrategy
|
|
1181
|
+
];
|
|
1182
|
+
}
|
|
1183
|
+
mount(vnode, context) {
|
|
1184
|
+
return this.findStrategy(vnode).mount(vnode, context);
|
|
1185
|
+
}
|
|
1186
|
+
patch(oldVNode, newVNode, currentNode, context) {
|
|
1187
|
+
const oldStrategy = this.findStrategy(oldVNode);
|
|
1188
|
+
const newStrategy = this.findStrategy(newVNode);
|
|
1189
|
+
if (oldStrategy !== newStrategy) {
|
|
1190
|
+
const nextNode = newStrategy.mount(newVNode, context);
|
|
1191
|
+
currentNode.parentNode?.replaceChild(nextNode, currentNode);
|
|
1192
|
+
oldStrategy.unmount(oldVNode, currentNode, context);
|
|
1193
|
+
return nextNode;
|
|
1194
|
+
}
|
|
1195
|
+
return oldStrategy.patch(oldVNode, newVNode, currentNode, context);
|
|
1196
|
+
}
|
|
1197
|
+
unmount(vnode, currentNode, context) {
|
|
1198
|
+
this.findStrategy(vnode).unmount(vnode, currentNode, context);
|
|
1199
|
+
}
|
|
1200
|
+
findStrategy(vnode) {
|
|
1201
|
+
const strategy = this.strategies.find((item) => item.matches(vnode));
|
|
1202
|
+
if (!strategy) {
|
|
1203
|
+
throw new Error("No render strategy found for vnode");
|
|
1204
|
+
}
|
|
1205
|
+
return strategy;
|
|
1206
|
+
}
|
|
1207
|
+
}
|
|
1208
|
+
|
|
1209
|
+
class TextRenderStrategy {
|
|
1210
|
+
matches(vnode) {
|
|
1211
|
+
return typeof vnode === "string";
|
|
1212
|
+
}
|
|
1213
|
+
mount(vnode, context) {
|
|
1214
|
+
return context.templateEngine.parseTemplate(vnode);
|
|
1215
|
+
}
|
|
1216
|
+
patch(oldVNode, newVNode, currentNode, context) {
|
|
1217
|
+
if (oldVNode === newVNode) {
|
|
1218
|
+
return currentNode;
|
|
1219
|
+
}
|
|
1220
|
+
const nextNode = this.mount(newVNode, context);
|
|
1221
|
+
currentNode.parentNode?.replaceChild(nextNode, currentNode);
|
|
1222
|
+
return nextNode;
|
|
1223
|
+
}
|
|
1224
|
+
unmount() {}
|
|
1225
|
+
}
|
|
1226
|
+
|
|
1227
|
+
class ComponentRenderStrategy {
|
|
1228
|
+
instances = new WeakMap;
|
|
1229
|
+
instanceNodes = new Map;
|
|
1230
|
+
emitterUnsubscribers = new WeakMap;
|
|
1231
|
+
matches(vnode) {
|
|
1232
|
+
return typeof vnode === "object" && vnode !== null && isComponentNode(vnode);
|
|
1233
|
+
}
|
|
1234
|
+
mount(vnode, context) {
|
|
1235
|
+
if (vnode.directions?.if === false) {
|
|
1236
|
+
return document.createComment("if");
|
|
1237
|
+
}
|
|
1238
|
+
const ComponentClass = vnode.component;
|
|
1239
|
+
const instance = new ComponentClass(this.createProps(vnode));
|
|
1240
|
+
if (context.appContext && instance.setAppContext) {
|
|
1241
|
+
instance.setAppContext(context.appContext);
|
|
1242
|
+
}
|
|
1243
|
+
this.syncEmitters(instance, vnode.emitters ?? {});
|
|
1244
|
+
context.registerChild(instance);
|
|
1245
|
+
const node = instance.mountToNode();
|
|
1246
|
+
this.trackInstanceNode(instance, node);
|
|
1247
|
+
instance.setElementChangeListener?.((previousNode, nextNode) => {
|
|
1248
|
+
this.trackInstanceNode(instance, previousNode);
|
|
1249
|
+
this.trackInstanceNode(instance, nextNode);
|
|
1250
|
+
});
|
|
1251
|
+
return node;
|
|
1252
|
+
}
|
|
1253
|
+
patch(oldVNode, newVNode, currentNode, context) {
|
|
1254
|
+
if (currentNode.nodeType === Node.COMMENT_NODE) {
|
|
1255
|
+
const nextNode2 = this.mount(newVNode, context);
|
|
1256
|
+
currentNode.parentNode?.replaceChild(nextNode2, currentNode);
|
|
1257
|
+
return nextNode2;
|
|
1258
|
+
}
|
|
1259
|
+
if (newVNode.directions?.if === false) {
|
|
1260
|
+
const nextNode2 = document.createComment("if");
|
|
1261
|
+
currentNode.parentNode?.replaceChild(nextNode2, currentNode);
|
|
1262
|
+
this.unmount(oldVNode, currentNode, context);
|
|
1263
|
+
return nextNode2;
|
|
1264
|
+
}
|
|
1265
|
+
const instance = this.instances.get(currentNode);
|
|
1266
|
+
if (instance && oldVNode.component === newVNode.component) {
|
|
1267
|
+
this.syncEmitters(instance, newVNode.emitters ?? {});
|
|
1268
|
+
instance.setProps(this.createProps(newVNode));
|
|
1269
|
+
const nextNode2 = instance.getElement() ?? currentNode;
|
|
1270
|
+
this.trackInstanceNode(instance, nextNode2);
|
|
1271
|
+
return nextNode2;
|
|
1272
|
+
}
|
|
1273
|
+
const nextNode = this.mount(newVNode, context);
|
|
1274
|
+
currentNode.parentNode?.replaceChild(nextNode, currentNode);
|
|
1275
|
+
this.unmount(oldVNode, currentNode, context);
|
|
1276
|
+
return nextNode;
|
|
1277
|
+
}
|
|
1278
|
+
unmount(_vnode, currentNode, context) {
|
|
1279
|
+
const instance = this.instances.get(currentNode);
|
|
1280
|
+
if (instance) {
|
|
1281
|
+
this.clearEmitters(instance);
|
|
1282
|
+
instance.unmount();
|
|
1283
|
+
this.clearInstanceNodes(instance);
|
|
1284
|
+
context.unregisterChild(instance);
|
|
1285
|
+
}
|
|
1286
|
+
}
|
|
1287
|
+
createProps(vnode) {
|
|
1288
|
+
return {
|
|
1289
|
+
...vnode.props ?? {},
|
|
1290
|
+
children: vnode.children ?? []
|
|
1291
|
+
};
|
|
1292
|
+
}
|
|
1293
|
+
syncEmitters(instance, emitters) {
|
|
1294
|
+
const current = this.emitterUnsubscribers.get(instance) ?? new Map;
|
|
1295
|
+
current.forEach(({ listener: currentListener, unsubscribe }, eventName) => {
|
|
1296
|
+
const listener = emitters[eventName];
|
|
1297
|
+
if (!listener || listener !== currentListener) {
|
|
1298
|
+
unsubscribe();
|
|
1299
|
+
current.delete(eventName);
|
|
1300
|
+
}
|
|
1301
|
+
});
|
|
1302
|
+
Object.entries(emitters).forEach(([eventName, listener]) => {
|
|
1303
|
+
if (current.get(eventName)?.listener === listener) {
|
|
827
1304
|
return;
|
|
828
1305
|
}
|
|
829
|
-
|
|
830
|
-
|
|
1306
|
+
current.set(eventName, {
|
|
1307
|
+
listener,
|
|
1308
|
+
unsubscribe: instance.on(eventName, listener)
|
|
1309
|
+
});
|
|
1310
|
+
});
|
|
1311
|
+
this.emitterUnsubscribers.set(instance, current);
|
|
831
1312
|
}
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
1313
|
+
clearEmitters(instance) {
|
|
1314
|
+
this.emitterUnsubscribers.get(instance)?.forEach(({ unsubscribe }) => {
|
|
1315
|
+
unsubscribe();
|
|
1316
|
+
});
|
|
1317
|
+
this.emitterUnsubscribers.delete(instance);
|
|
1318
|
+
}
|
|
1319
|
+
trackInstanceNode(instance, node) {
|
|
1320
|
+
this.instances.set(node, instance);
|
|
1321
|
+
const nodes = this.instanceNodes.get(instance) ?? new Set;
|
|
1322
|
+
nodes.add(node);
|
|
1323
|
+
this.instanceNodes.set(instance, nodes);
|
|
1324
|
+
}
|
|
1325
|
+
clearInstanceNodes(instance) {
|
|
1326
|
+
this.instanceNodes.get(instance)?.forEach((node) => {
|
|
1327
|
+
this.instances.delete(node);
|
|
1328
|
+
});
|
|
1329
|
+
this.instanceNodes.delete(instance);
|
|
1330
|
+
}
|
|
1331
|
+
}
|
|
1332
|
+
|
|
1333
|
+
class SlotRenderStrategy {
|
|
1334
|
+
renderedChildren = new WeakMap;
|
|
1335
|
+
matches(vnode) {
|
|
1336
|
+
return typeof vnode === "object" && vnode !== null && isSlotProvider(vnode);
|
|
1337
|
+
}
|
|
1338
|
+
mount(vnode, context) {
|
|
1339
|
+
if (vnode.directions?.if === false) {
|
|
1340
|
+
return document.createComment("if");
|
|
1341
|
+
}
|
|
1342
|
+
const slotContainer = document.createElement("div");
|
|
1343
|
+
slotContainer.setAttribute("data-slot", vnode.props.name);
|
|
1344
|
+
this.mountSlotChildren(slotContainer, this.resolveChildren(vnode, context), context);
|
|
1345
|
+
return slotContainer;
|
|
1346
|
+
}
|
|
1347
|
+
patch(oldVNode, newVNode, currentNode, context) {
|
|
1348
|
+
if (currentNode.nodeType === Node.COMMENT_NODE) {
|
|
1349
|
+
const nextNode = this.mount(newVNode, context);
|
|
1350
|
+
currentNode.parentNode?.replaceChild(nextNode, currentNode);
|
|
1351
|
+
return nextNode;
|
|
1352
|
+
}
|
|
1353
|
+
if (newVNode.directions?.if === false) {
|
|
1354
|
+
const nextNode = document.createComment("if");
|
|
1355
|
+
currentNode.parentNode?.replaceChild(nextNode, currentNode);
|
|
1356
|
+
this.unmount(oldVNode, currentNode, context);
|
|
1357
|
+
return nextNode;
|
|
1358
|
+
}
|
|
1359
|
+
if (currentNode instanceof HTMLElement) {
|
|
1360
|
+
currentNode.setAttribute("data-slot", newVNode.props.name);
|
|
1361
|
+
this.replaceSlotChildren(currentNode, oldVNode, newVNode, context);
|
|
1362
|
+
}
|
|
1363
|
+
return currentNode;
|
|
1364
|
+
}
|
|
1365
|
+
unmount(_vnode, currentNode, context) {
|
|
1366
|
+
if (!(currentNode instanceof HTMLElement)) {
|
|
1367
|
+
return;
|
|
1368
|
+
}
|
|
1369
|
+
this.unmountSlotChildren(currentNode, context);
|
|
1370
|
+
this.renderedChildren.delete(currentNode);
|
|
1371
|
+
}
|
|
1372
|
+
resolveChildren(vnode, context) {
|
|
1373
|
+
return context.slots[vnode.props.name] ?? vnode.children ?? [];
|
|
1374
|
+
}
|
|
1375
|
+
replaceSlotChildren(element, _oldVNode, newVNode, context) {
|
|
1376
|
+
this.unmountSlotChildren(element, context);
|
|
1377
|
+
element.textContent = "";
|
|
1378
|
+
this.mountSlotChildren(element, this.resolveChildren(newVNode, context), context);
|
|
1379
|
+
}
|
|
1380
|
+
mountSlotChildren(element, children, context) {
|
|
1381
|
+
children.forEach((child) => {
|
|
1382
|
+
element.appendChild(context.renderer.mount(child, context));
|
|
1383
|
+
});
|
|
1384
|
+
this.renderedChildren.set(element, children);
|
|
1385
|
+
}
|
|
1386
|
+
unmountSlotChildren(element, context) {
|
|
1387
|
+
const children = this.renderedChildren.get(element) ?? [];
|
|
1388
|
+
children.forEach((child, index) => {
|
|
1389
|
+
const childNode = element.childNodes[index];
|
|
1390
|
+
if (childNode) {
|
|
1391
|
+
context.renderer.unmount(child, childNode, context);
|
|
1392
|
+
}
|
|
1393
|
+
});
|
|
836
1394
|
}
|
|
837
1395
|
}
|
|
838
1396
|
|
|
@@ -889,8 +1447,8 @@ class TemplateEngine {
|
|
|
889
1447
|
if (key) {
|
|
890
1448
|
keys.add(key);
|
|
891
1449
|
const value = this.getValueFromState(key);
|
|
892
|
-
const
|
|
893
|
-
result = result.replace(match[0],
|
|
1450
|
+
const displayValue2 = value === undefined || value === null ? "" : String(value);
|
|
1451
|
+
result = result.replace(match[0], displayValue2);
|
|
894
1452
|
}
|
|
895
1453
|
});
|
|
896
1454
|
return result;
|
|
@@ -910,7 +1468,7 @@ class TemplateEngine {
|
|
|
910
1468
|
}
|
|
911
1469
|
clearBindings() {
|
|
912
1470
|
this.bindings.forEach((binding) => {
|
|
913
|
-
binding.effect
|
|
1471
|
+
stop(binding.effect);
|
|
914
1472
|
});
|
|
915
1473
|
this.bindings = [];
|
|
916
1474
|
}
|
|
@@ -953,8 +1511,11 @@ class Component {
|
|
|
953
1511
|
templateEngine;
|
|
954
1512
|
childComponents = new Set;
|
|
955
1513
|
eventListeners = {};
|
|
1514
|
+
providers = new Map;
|
|
956
1515
|
updateEffect;
|
|
957
1516
|
appContext = null;
|
|
1517
|
+
parentComponent = null;
|
|
1518
|
+
elementChangeListener = null;
|
|
958
1519
|
styleManager;
|
|
959
1520
|
state;
|
|
960
1521
|
mounted = false;
|
|
@@ -969,7 +1530,7 @@ class Component {
|
|
|
969
1530
|
if (this.mounted) {
|
|
970
1531
|
this.update();
|
|
971
1532
|
}
|
|
972
|
-
});
|
|
1533
|
+
}, { throwOnError: true });
|
|
973
1534
|
}
|
|
974
1535
|
mount(container) {
|
|
975
1536
|
if (!container || !(container instanceof HTMLElement)) {
|
|
@@ -997,15 +1558,15 @@ class Component {
|
|
|
997
1558
|
if (!this.el || !this.vnode) {
|
|
998
1559
|
return;
|
|
999
1560
|
}
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
this.
|
|
1006
|
-
} catch (error) {
|
|
1007
|
-
console.error("组件更新错误:", error);
|
|
1561
|
+
this.beforeUpdate();
|
|
1562
|
+
const newVNode = this.render();
|
|
1563
|
+
const previousElement = this.el;
|
|
1564
|
+
this.el = this.renderer.patch(this.vnode, newVNode, this.el, this.createRenderContext());
|
|
1565
|
+
if (previousElement !== this.el) {
|
|
1566
|
+
this.elementChangeListener?.(previousElement, this.el);
|
|
1008
1567
|
}
|
|
1568
|
+
this.vnode = newVNode;
|
|
1569
|
+
this.onUpdated();
|
|
1009
1570
|
}
|
|
1010
1571
|
unmount() {
|
|
1011
1572
|
if (!this.mounted) {
|
|
@@ -1016,8 +1577,15 @@ class Component {
|
|
|
1016
1577
|
this.renderer.unmount(this.vnode, this.el, this.createRenderContext());
|
|
1017
1578
|
}
|
|
1018
1579
|
this.childComponents.clear();
|
|
1580
|
+
Object.keys(this.eventListeners).forEach((eventName) => {
|
|
1581
|
+
this.eventListeners[eventName].clear();
|
|
1582
|
+
delete this.eventListeners[eventName];
|
|
1583
|
+
});
|
|
1584
|
+
this.providers.clear();
|
|
1585
|
+
this.parentComponent = null;
|
|
1586
|
+
this.elementChangeListener = null;
|
|
1019
1587
|
this.templateEngine.clearBindings();
|
|
1020
|
-
this.styleManager.
|
|
1588
|
+
this.styleManager.destroy();
|
|
1021
1589
|
stop(this.updateEffect);
|
|
1022
1590
|
if (this.el?.parentNode) {
|
|
1023
1591
|
this.el.parentNode.removeChild(this.el);
|
|
@@ -1045,6 +1613,28 @@ class Component {
|
|
|
1045
1613
|
child.setAppContext?.(context);
|
|
1046
1614
|
});
|
|
1047
1615
|
}
|
|
1616
|
+
setParentComponent(parent) {
|
|
1617
|
+
this.parentComponent = parent;
|
|
1618
|
+
}
|
|
1619
|
+
setElementChangeListener(listener) {
|
|
1620
|
+
this.elementChangeListener = listener;
|
|
1621
|
+
}
|
|
1622
|
+
provide(key, value) {
|
|
1623
|
+
this.providers.set(key, value);
|
|
1624
|
+
}
|
|
1625
|
+
inject(key, fallback) {
|
|
1626
|
+
const result = this.resolveInjection(key);
|
|
1627
|
+
return result.found ? result.value : fallback;
|
|
1628
|
+
}
|
|
1629
|
+
resolveInjection(key) {
|
|
1630
|
+
if (this.providers.has(key)) {
|
|
1631
|
+
return { found: true, value: this.providers.get(key) };
|
|
1632
|
+
}
|
|
1633
|
+
if (this.parentComponent?.resolveInjection) {
|
|
1634
|
+
return this.parentComponent.resolveInjection(key);
|
|
1635
|
+
}
|
|
1636
|
+
return this.resolveAppInjection(key);
|
|
1637
|
+
}
|
|
1048
1638
|
getElement() {
|
|
1049
1639
|
return this.el;
|
|
1050
1640
|
}
|
|
@@ -1070,6 +1660,7 @@ class Component {
|
|
|
1070
1660
|
this.eventListeners[eventName] = new Set;
|
|
1071
1661
|
}
|
|
1072
1662
|
this.eventListeners[eventName].add(listener);
|
|
1663
|
+
return () => this.off(eventName, listener);
|
|
1073
1664
|
}
|
|
1074
1665
|
off(eventName, listener) {
|
|
1075
1666
|
this.eventListeners[eventName]?.delete(listener);
|
|
@@ -1082,7 +1673,12 @@ class Component {
|
|
|
1082
1673
|
slots: this.collectSlots(),
|
|
1083
1674
|
registerChild: (component) => {
|
|
1084
1675
|
this.childComponents.add(component);
|
|
1676
|
+
component.setParentComponent?.(this);
|
|
1085
1677
|
component.setAppContext?.(this.appContext);
|
|
1678
|
+
},
|
|
1679
|
+
unregisterChild: (component) => {
|
|
1680
|
+
this.childComponents.delete(component);
|
|
1681
|
+
component.setParentComponent?.(null);
|
|
1086
1682
|
}
|
|
1087
1683
|
};
|
|
1088
1684
|
}
|
|
@@ -1125,6 +1721,13 @@ class Component {
|
|
|
1125
1721
|
const globalApp = globalThis.__APP__;
|
|
1126
1722
|
return this.getRouterFrom(globalApp);
|
|
1127
1723
|
}
|
|
1724
|
+
resolveAppInjection(key) {
|
|
1725
|
+
if (!this.appContext || typeof this.appContext !== "object") {
|
|
1726
|
+
return { found: false, value: undefined };
|
|
1727
|
+
}
|
|
1728
|
+
const app = this.appContext.app;
|
|
1729
|
+
return app?.resolveInjection?.(key) ?? { found: false, value: undefined };
|
|
1730
|
+
}
|
|
1128
1731
|
trackReactiveValue(value, seen) {
|
|
1129
1732
|
if (!value || typeof value !== "object" || seen.has(value)) {
|
|
1130
1733
|
return;
|
|
@@ -1147,6 +1750,12 @@ function setRouter(r) {
|
|
|
1147
1750
|
}
|
|
1148
1751
|
router = r;
|
|
1149
1752
|
}
|
|
1753
|
+
function useRouter() {
|
|
1754
|
+
if (!router) {
|
|
1755
|
+
throw new Error("Router is not initialized. Please make sure you have installed the router plugin.");
|
|
1756
|
+
}
|
|
1757
|
+
return router;
|
|
1758
|
+
}
|
|
1150
1759
|
|
|
1151
1760
|
// lib/router/matcher.ts
|
|
1152
1761
|
function normalizePath(path) {
|
|
@@ -1207,13 +1816,18 @@ function createRouterHref(path, mode, base) {
|
|
|
1207
1816
|
function getBrowserLocation(mode, base) {
|
|
1208
1817
|
let path;
|
|
1209
1818
|
let fullPath;
|
|
1819
|
+
let queryString;
|
|
1210
1820
|
if (mode === "history") {
|
|
1211
1821
|
fullPath = window.location.pathname + window.location.search;
|
|
1212
1822
|
path = window.location.pathname;
|
|
1823
|
+
queryString = window.location.search;
|
|
1213
1824
|
} else {
|
|
1214
1825
|
const hash = window.location.hash;
|
|
1215
1826
|
fullPath = hash || "#/";
|
|
1216
1827
|
path = fullPath.startsWith("#") ? fullPath.slice(1) : fullPath;
|
|
1828
|
+
const queryStart = path.indexOf("?");
|
|
1829
|
+
queryString = queryStart >= 0 ? path.slice(queryStart + 1) : "";
|
|
1830
|
+
path = queryStart >= 0 ? path.slice(0, queryStart) : path;
|
|
1217
1831
|
}
|
|
1218
1832
|
if (path.startsWith(base) && base !== "/" && path !== "/") {
|
|
1219
1833
|
path = path.slice(base.length);
|
|
@@ -1222,7 +1836,7 @@ function getBrowserLocation(mode, base) {
|
|
|
1222
1836
|
return {
|
|
1223
1837
|
path,
|
|
1224
1838
|
fullPath,
|
|
1225
|
-
query: parseQuery(
|
|
1839
|
+
query: parseQuery(queryString),
|
|
1226
1840
|
params: {}
|
|
1227
1841
|
};
|
|
1228
1842
|
}
|
|
@@ -1492,7 +2106,7 @@ function createRouter(options) {
|
|
|
1492
2106
|
return new Router(options);
|
|
1493
2107
|
}
|
|
1494
2108
|
|
|
1495
|
-
export { ReactiveSystem, reactive, readonly, effect, computed, stop, isReactive, isReadonly,
|
|
2109
|
+
export { isComponentNode, isHTMLNode, isSlotProvider, h, Tag, Div, Span, P, Button, Input, Section, Main, Header, Footer, Nav, Article, Aside, H1, H2, H3, H4, H5, H6, Strong, Em, Small, Pre, Code, Blockquote, Ul, Ol, Li, A, Img, Form, Label, Textarea, Select, Option, Table, Thead, Tbody, Tr, Th, Td, createComponent, slot, each, ReactiveSystem, reactive, readonly, effect, computed, ref, isRef, unref, stop, isReactive, isReadonly, modelPath, getModelValue, setModelValue, ModelBindingController, ElementRenderStrategy, normalizeTransitionGroupProps, validateTransitionGroupChildren, RendererContext, TextRenderStrategy, ComponentRenderStrategy, SlotRenderStrategy, TemplateEngine, Component, useRouter, Router, RouterLink, RouterView, createRouter };
|
|
1496
2110
|
|
|
1497
|
-
//# debugId=
|
|
1498
|
-
//# sourceMappingURL=index-
|
|
2111
|
+
//# debugId=91AF0EEFB67A584364756E2164756E21
|
|
2112
|
+
//# sourceMappingURL=index-wv9gyjqt.js.map
|