@expressive/dom 0.3.0 → 0.4.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.md +4 -4
- package/dist/{chunk-adapter-4jlvwsge.d.ts → chunk-adapter-i1piHw8T.d.ts} +14 -14
- package/dist/{chunk-hot-BAqPvKEQ.js → chunk-hot-9LhRiwFx.js} +13 -13
- package/dist/chunk-hot-9LhRiwFx.js.map +1 -0
- package/dist/{chunk-loader-kjuM318E.d.ts → chunk-loader-CZ-53pyV.d.ts} +3 -3
- package/dist/{chunk-vnode-BG1Cv8F9.js → chunk-vnode-wpCWQ_Zg.js} +2 -2
- package/dist/chunk-vnode-wpCWQ_Zg.js.map +1 -0
- package/dist/index.d.ts +7 -4
- package/dist/index.js +814 -762
- package/dist/index.js.map +1 -1
- package/dist/jsx-dev-runtime.d.ts +2 -2
- package/dist/jsx-dev-runtime.js +2 -2
- package/dist/jsx-dev-runtime.js.map +1 -1
- package/dist/jsx-runtime.d.ts +10 -10
- package/dist/jsx-runtime.js +1 -1
- package/dist/jsx-runtime.js.map +1 -1
- package/dist/vite.js +4 -4
- package/dist/vite.js.map +1 -1
- package/package.json +3 -2
- package/dist/chunk-hot-BAqPvKEQ.js.map +0 -1
- package/dist/chunk-vnode-BG1Cv8F9.js.map +0 -1
package/dist/index.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import { a as untrack, c as dispose, d as claim$1, f as release, h as transition, i as track, l as enter, m as settle$1, n as latest, o as call, p as schedule, r as same, s as commit, u as afterFlush } from "./chunk-hot-
|
|
2
|
-
import { a as createElement, i as childrenOf, n as PORTAL, o as isVNode, r as Portal, s as vnode, t as Fragment } from "./chunk-vnode-
|
|
1
|
+
import { a as untrack, c as dispose, d as claim$1, f as release, h as transition, i as track, l as enter, m as settle$1, n as latest, o as call, p as schedule, r as same, s as commit, u as afterFlush } from "./chunk-hot-9LhRiwFx.js";
|
|
2
|
+
import { a as createElement, i as childrenOf, n as PORTAL, o as isVNode, r as Portal, s as vnode, t as Fragment } from "./chunk-vnode-wpCWQ_Zg.js";
|
|
3
3
|
import "./jsx-runtime.js";
|
|
4
|
-
import { Component, Context,
|
|
4
|
+
import { Component, Context, Model, has, map, unbind } from "@expressive/mvc";
|
|
5
5
|
import { watch } from "@expressive/mvc/observable";
|
|
6
|
-
import { Fragment as Fragment$1
|
|
6
|
+
import { Fragment as Fragment$1 } from "@expressive/mvc/jsx-runtime";
|
|
7
7
|
|
|
8
|
-
//#region src/css.ts
|
|
8
|
+
//#region src/style/css.ts
|
|
9
9
|
const unitless = /* @__PURE__ */ new Map();
|
|
10
10
|
let probe;
|
|
11
11
|
/**
|
|
@@ -58,7 +58,7 @@ const css = {
|
|
|
58
58
|
};
|
|
59
59
|
|
|
60
60
|
//#endregion
|
|
61
|
-
//#region src/
|
|
61
|
+
//#region src/style/protocol.ts
|
|
62
62
|
const registrations = /* @__PURE__ */ new WeakMap();
|
|
63
63
|
const tokens = /* @__PURE__ */ new WeakMap();
|
|
64
64
|
let root;
|
|
@@ -105,7 +105,7 @@ function appearanceToken(value) {
|
|
|
105
105
|
}
|
|
106
106
|
|
|
107
107
|
//#endregion
|
|
108
|
-
//#region src/appearance.ts
|
|
108
|
+
//#region src/style/appearance.ts
|
|
109
109
|
const bases = /* @__PURE__ */ new WeakMap();
|
|
110
110
|
const chains = /* @__PURE__ */ new WeakMap();
|
|
111
111
|
const contexts = /* @__PURE__ */ new WeakMap();
|
|
@@ -332,7 +332,7 @@ function isObject(value) {
|
|
|
332
332
|
}
|
|
333
333
|
|
|
334
334
|
//#endregion
|
|
335
|
-
//#region src/declarations.ts
|
|
335
|
+
//#region src/style/declarations.ts
|
|
336
336
|
function applyDeclarations(style, declarations, previous = {}) {
|
|
337
337
|
const target = style;
|
|
338
338
|
for (const key of Object.keys({
|
|
@@ -351,7 +351,7 @@ function applyDeclarations(style, declarations, previous = {}) {
|
|
|
351
351
|
}
|
|
352
352
|
|
|
353
353
|
//#endregion
|
|
354
|
-
//#region src/stylesheet.ts
|
|
354
|
+
//#region src/style/stylesheet.ts
|
|
355
355
|
const sheets = /* @__PURE__ */ new WeakMap();
|
|
356
356
|
function style(type, rules) {
|
|
357
357
|
style$1(type, rules);
|
|
@@ -403,31 +403,7 @@ function serialize(document, declarations) {
|
|
|
403
403
|
}
|
|
404
404
|
|
|
405
405
|
//#endregion
|
|
406
|
-
//#region src/
|
|
407
|
-
const LOADS = /* @__PURE__ */ new WeakMap();
|
|
408
|
-
function resolve(type, props, run) {
|
|
409
|
-
const load = LOADS.get(type);
|
|
410
|
-
if (load?.resolved) return vnode(load.resolved, props);
|
|
411
|
-
if (load?.failed) {
|
|
412
|
-
LOADS.delete(type);
|
|
413
|
-
throw load.failed.error;
|
|
414
|
-
}
|
|
415
|
-
if (load) throw load.pending;
|
|
416
|
-
const output = run();
|
|
417
|
-
if (!output || typeof output.then != "function") return output;
|
|
418
|
-
const next = {};
|
|
419
|
-
LOADS.set(type, next);
|
|
420
|
-
throw next.pending = output.then((module) => {
|
|
421
|
-
const component = typeof module == "function" ? module : module?.default;
|
|
422
|
-
if (typeof component == "function") next.resolved = component;
|
|
423
|
-
else next.failed = { error: /* @__PURE__ */ new Error("Loader resolved no component.") };
|
|
424
|
-
}, (error) => {
|
|
425
|
-
next.failed = { error };
|
|
426
|
-
});
|
|
427
|
-
}
|
|
428
|
-
|
|
429
|
-
//#endregion
|
|
430
|
-
//#region src/commits.ts
|
|
406
|
+
//#region src/render/commits.ts
|
|
431
407
|
const DETACHED = /* @__PURE__ */ new WeakMap();
|
|
432
408
|
let batch;
|
|
433
409
|
/** Run `run` once `fiber` is on the page: now, after the current batch, or when its detached root attaches. */
|
|
@@ -468,63 +444,7 @@ function deliver(entry) {
|
|
|
468
444
|
}
|
|
469
445
|
|
|
470
446
|
//#endregion
|
|
471
|
-
//#region src/render.ts
|
|
472
|
-
const roots = /* @__PURE__ */ new WeakMap();
|
|
473
|
-
const SVG = "http://www.w3.org/2000/svg";
|
|
474
|
-
const dirty = /* @__PURE__ */ new Set();
|
|
475
|
-
const stashes = /* @__PURE__ */ new WeakMap();
|
|
476
|
-
const CONTROLS = ["checked", "value"];
|
|
477
|
-
const ENUMERATED = [
|
|
478
|
-
"contentEditable",
|
|
479
|
-
"contenteditable",
|
|
480
|
-
"draggable",
|
|
481
|
-
"spellcheck"
|
|
482
|
-
];
|
|
483
|
-
const ALIASES = {
|
|
484
|
-
autoFocus: "autofocus",
|
|
485
|
-
contentEditable: "contenteditable",
|
|
486
|
-
htmlFor: "for"
|
|
487
|
-
};
|
|
488
|
-
const focusing = [];
|
|
489
|
-
const controlled = /* @__PURE__ */ new WeakMap();
|
|
490
|
-
const restoring = /* @__PURE__ */ new WeakSet();
|
|
491
|
-
let passiveRender = false;
|
|
492
|
-
let holding;
|
|
493
|
-
let depth = 0;
|
|
494
|
-
let settling = false;
|
|
495
|
-
let rendering;
|
|
496
|
-
let touched = false;
|
|
497
|
-
const observed = /* @__PURE__ */ new WeakMap();
|
|
498
|
-
const tickets = /* @__PURE__ */ new WeakMap();
|
|
499
|
-
function render(node, container) {
|
|
500
|
-
roots.get(container)?.();
|
|
501
|
-
container.replaceChildren();
|
|
502
|
-
const context = new Context(Context.root);
|
|
503
|
-
const fiber = range("fragment", container, null, context);
|
|
504
|
-
try {
|
|
505
|
-
pass(() => {
|
|
506
|
-
const appearanceContext = appearanceRoot();
|
|
507
|
-
reconcile(fiber, node, context, void 0, appearanceContext ? {
|
|
508
|
-
context: appearanceContext,
|
|
509
|
-
entries: []
|
|
510
|
-
} : void 0);
|
|
511
|
-
});
|
|
512
|
-
} catch (error) {
|
|
513
|
-
unmountFiber(fiber);
|
|
514
|
-
context.pop();
|
|
515
|
-
throw error;
|
|
516
|
-
}
|
|
517
|
-
let active = true;
|
|
518
|
-
const unmount = () => {
|
|
519
|
-
if (!active) return;
|
|
520
|
-
active = false;
|
|
521
|
-
unmountFiber(fiber);
|
|
522
|
-
context.pop();
|
|
523
|
-
roots.delete(container);
|
|
524
|
-
};
|
|
525
|
-
roots.set(container, unmount);
|
|
526
|
-
return unmount;
|
|
527
|
-
}
|
|
447
|
+
//#region src/render/fiber.ts
|
|
528
448
|
function range(kind, parent, before, context) {
|
|
529
449
|
const start = document.createComment(kind);
|
|
530
450
|
const end = document.createComment(`/${kind}`);
|
|
@@ -550,170 +470,37 @@ function makeScope(kind, context, update) {
|
|
|
550
470
|
uses: []
|
|
551
471
|
};
|
|
552
472
|
}
|
|
553
|
-
function
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
if (holding && error === holding.thrown) {
|
|
561
|
-
park(fiber);
|
|
562
|
-
holding.fiber = fiber;
|
|
563
|
-
} else unmountFiber(fiber);
|
|
564
|
-
throw error;
|
|
473
|
+
function moveRange(start, end, target) {
|
|
474
|
+
let node = start;
|
|
475
|
+
while (node) {
|
|
476
|
+
const next = node.nextSibling;
|
|
477
|
+
target.appendChild(node);
|
|
478
|
+
if (node === end) break;
|
|
479
|
+
node = next;
|
|
565
480
|
}
|
|
566
|
-
return fiber;
|
|
567
|
-
}
|
|
568
|
-
function componentProps(type, props, appearance) {
|
|
569
|
-
const context = appearance?.context;
|
|
570
|
-
if (!context || typeof type != "function") return {
|
|
571
|
-
appearance,
|
|
572
|
-
props
|
|
573
|
-
};
|
|
574
|
-
const value = context.resolve(props);
|
|
575
|
-
const entries = appearance.entries;
|
|
576
|
-
if (!value) return {
|
|
577
|
-
appearance: { entries },
|
|
578
|
-
props
|
|
579
|
-
};
|
|
580
|
-
return {
|
|
581
|
-
appearance: {
|
|
582
|
-
context: value.context,
|
|
583
|
-
entries
|
|
584
|
-
},
|
|
585
|
-
props: {
|
|
586
|
-
...props,
|
|
587
|
-
style: [createAppearanceToken(value), props.style]
|
|
588
|
-
}
|
|
589
|
-
};
|
|
590
481
|
}
|
|
591
|
-
function
|
|
592
|
-
if (
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
start: text,
|
|
600
|
-
end: text,
|
|
601
|
-
children: []
|
|
602
|
-
};
|
|
482
|
+
function move(fiber, parent, before) {
|
|
483
|
+
if (fiber.start.parentNode === parent && fiber.end.nextSibling === before) return;
|
|
484
|
+
let node = fiber.start;
|
|
485
|
+
while (node) {
|
|
486
|
+
const next = node.nextSibling;
|
|
487
|
+
parent.insertBefore(node, before);
|
|
488
|
+
if (node === fiber.end) break;
|
|
489
|
+
node = next;
|
|
603
490
|
}
|
|
604
|
-
if (renderable(value)) return mountComponent(value, parent, before, context, boundary, appearance);
|
|
605
|
-
if (isCollection(value)) return mountCollection(value, parent, before, context, boundary, appearance);
|
|
606
|
-
if (!isVNode(value)) throw new TypeError(`Cannot render ${String(value)}.`);
|
|
607
|
-
if (value.type === Fragment$1) return mountFragment(value, parent, before, context, boundary, appearance);
|
|
608
|
-
if (value.type === PORTAL) return mountPortal(value, parent, before, context, boundary, appearance);
|
|
609
|
-
if (typeof value.type == "string") return mountElement(value, parent, before, context, boundary, appearance);
|
|
610
|
-
if (typeof value.type != "function") throw new Error(`Cannot render ${String(value.type)}.`);
|
|
611
|
-
if (value.type.prototype instanceof State) return mountOwnedComponent(value, parent, before, context, boundary, appearance);
|
|
612
|
-
return mountFunction(value, parent, before, context, boundary, appearance);
|
|
613
|
-
}
|
|
614
|
-
function mountFragment(value, parent, before, context, boundary, appearance) {
|
|
615
|
-
const fiber = range("fragment", parent, before, context);
|
|
616
|
-
fiber.key = value.key;
|
|
617
|
-
fiber.type = Fragment$1;
|
|
618
|
-
fiber.appearance = appearance;
|
|
619
|
-
return complete(fiber, () => {
|
|
620
|
-
reconcile(fiber, value.props.children, context, boundary, appearance);
|
|
621
|
-
});
|
|
622
|
-
}
|
|
623
|
-
function mountFunction(value, parent, before, context, boundary, appearance) {
|
|
624
|
-
const fiber = range("function", parent, before, context);
|
|
625
|
-
const resolved = componentProps(value.type, value.props, appearance);
|
|
626
|
-
fiber.key = value.key;
|
|
627
|
-
fiber.type = value.type;
|
|
628
|
-
fiber.props = observe(resolved.props);
|
|
629
|
-
fiber.boundary = boundary;
|
|
630
|
-
fiber.appearance = resolved.appearance;
|
|
631
|
-
fiber.scope = makeScope("function", context, (passive) => runFunction(fiber, passive));
|
|
632
|
-
fiber.render = () => enter(fiber.scope, () => {
|
|
633
|
-
const type = latest(fiber.type);
|
|
634
|
-
return resolve(type, fiber.props, () => call(type, fiber.props));
|
|
635
|
-
});
|
|
636
|
-
track(fiber.type, fiber.scope);
|
|
637
|
-
probing(fiber);
|
|
638
|
-
return complete(fiber, () => {
|
|
639
|
-
runFunction(fiber, passiveRender);
|
|
640
|
-
});
|
|
641
|
-
}
|
|
642
|
-
function mountOwnedComponent(value, parent, before, context, boundary, appearance) {
|
|
643
|
-
const resolved = componentProps(value.type, value.props, appearance);
|
|
644
|
-
const Type = value.type;
|
|
645
|
-
const props = observe(resolved.props);
|
|
646
|
-
const instance = new Type(props, Type.prototype instanceof Component ? void 0 : () => props.is?.(instance));
|
|
647
|
-
return mountComponent(instance, parent, before, context, boundary, resolved.appearance, true, value.key, props);
|
|
648
|
-
}
|
|
649
|
-
function runFunction(fiber, passive) {
|
|
650
|
-
const result = attempt(fiber, passive, fiber.render);
|
|
651
|
-
if (result === true) inserted(fiber, () => commit(fiber.scope));
|
|
652
|
-
else return result;
|
|
653
|
-
}
|
|
654
|
-
function probing(fiber) {
|
|
655
|
-
const scope = fiber.scope;
|
|
656
|
-
scope.empty = () => !fiber.children.length;
|
|
657
|
-
scope.probe = () => {
|
|
658
|
-
try {
|
|
659
|
-
scope.probed = { output: consume(fiber, fiber.render) };
|
|
660
|
-
} catch (thrown) {
|
|
661
|
-
if (isThenable(thrown)) return thrown;
|
|
662
|
-
}
|
|
663
|
-
};
|
|
664
491
|
}
|
|
665
|
-
function
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
return (owned && fiber.props.catch || instance.catch).call(instance, error, instance);
|
|
673
|
-
} : void 0,
|
|
674
|
-
fallback: () => {
|
|
675
|
-
const placed = owned ? fiber.props.fallback : void 0;
|
|
676
|
-
return placed !== void 0 ? placed : instance.fallback;
|
|
677
|
-
},
|
|
678
|
-
owner: fiber,
|
|
679
|
-
parent: inherited
|
|
680
|
-
} : inherited;
|
|
681
|
-
fiber.boundary = ownBoundary;
|
|
682
|
-
if (ownBoundary !== inherited) fiber.ownBoundary = ownBoundary;
|
|
683
|
-
fiber.childContext = childContext;
|
|
684
|
-
fiber.instance = instance;
|
|
685
|
-
fiber.key = owned ? key : instance.key;
|
|
686
|
-
fiber.type = instance.constructor;
|
|
687
|
-
fiber.props = props;
|
|
688
|
-
fiber.owned = owned;
|
|
689
|
-
fiber.appearance = appearance;
|
|
690
|
-
fiber.scope = makeScope("component", childContext, (passive) => runComponent(fiber, passive));
|
|
691
|
-
fiber.render = () => enter(fiber.scope, () => compose.call(fiber.value, fiber.props));
|
|
692
|
-
probing(fiber);
|
|
693
|
-
let first = true;
|
|
694
|
-
let proxy = instance;
|
|
695
|
-
fiber.release = watch(instance, (current, events) => {
|
|
696
|
-
const { applied, scope } = fiber;
|
|
697
|
-
proxy = current;
|
|
698
|
-
fiber.applied = void 0;
|
|
699
|
-
if (!first && scope.active) if (applied && events.includes("props")) transition(() => schedule(scope));
|
|
700
|
-
else schedule(scope);
|
|
701
|
-
first = false;
|
|
702
|
-
}, void 0, transition);
|
|
703
|
-
Object.defineProperty(fiber, "value", { get: () => proxy });
|
|
704
|
-
try {
|
|
705
|
-
complete(fiber, () => {
|
|
706
|
-
runComponent(fiber, passiveRender);
|
|
707
|
-
});
|
|
708
|
-
} finally {
|
|
709
|
-
if (owned && !fiber.dead) inserted(fiber, () => fiber.cleanup = instance.mount?.());
|
|
492
|
+
function removeRange(start, end) {
|
|
493
|
+
let node = start;
|
|
494
|
+
while (true) {
|
|
495
|
+
const next = node.nextSibling;
|
|
496
|
+
node.remove();
|
|
497
|
+
if (node === end) break;
|
|
498
|
+
node = next;
|
|
710
499
|
}
|
|
711
|
-
return fiber;
|
|
712
|
-
}
|
|
713
|
-
function runComponent(fiber, passive) {
|
|
714
|
-
const result = attempt(fiber, passive, fiber.render);
|
|
715
|
-
if (result !== true) return result;
|
|
716
500
|
}
|
|
501
|
+
|
|
502
|
+
//#endregion
|
|
503
|
+
//#region src/render/collection.ts
|
|
717
504
|
function mountCollection(value, parent, before, context, boundary, appearance) {
|
|
718
505
|
const fiber = range("collection", parent, before, context);
|
|
719
506
|
fiber.source = value;
|
|
@@ -737,107 +524,159 @@ function runCollection(fiber, passive) {
|
|
|
737
524
|
return value instanceof map.Managed ? [...value.values()] : [...value];
|
|
738
525
|
});
|
|
739
526
|
}
|
|
740
|
-
function
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
527
|
+
function patchCollection(fiber, appearance) {
|
|
528
|
+
if (fiber.appearance === appearance) return;
|
|
529
|
+
fiber.appearance = appearance;
|
|
530
|
+
runCollection(fiber, passiveRender);
|
|
531
|
+
}
|
|
532
|
+
function isCollection(value) {
|
|
533
|
+
return value instanceof has.List || value instanceof has.Pool || value instanceof map.Managed;
|
|
534
|
+
}
|
|
535
|
+
|
|
536
|
+
//#endregion
|
|
537
|
+
//#region src/node/loader.ts
|
|
538
|
+
const LOADS = /* @__PURE__ */ new WeakMap();
|
|
539
|
+
function resolve(type, props, run) {
|
|
540
|
+
const load = LOADS.get(type);
|
|
541
|
+
if (load?.resolved) return vnode(load.resolved, props);
|
|
542
|
+
if (load?.failed) {
|
|
543
|
+
LOADS.delete(type);
|
|
544
|
+
throw load.failed.error;
|
|
545
|
+
}
|
|
546
|
+
if (load) throw load.pending;
|
|
547
|
+
const output = run();
|
|
548
|
+
if (!output || typeof output.then != "function") return output;
|
|
549
|
+
const next = {};
|
|
550
|
+
LOADS.set(type, next);
|
|
551
|
+
throw next.pending = output.then((module) => {
|
|
552
|
+
const component = typeof module == "function" ? module : module?.default;
|
|
553
|
+
if (typeof component == "function") next.resolved = component;
|
|
554
|
+
else next.failed = { error: /* @__PURE__ */ new Error("Loader resolved no component.") };
|
|
555
|
+
}, (error) => {
|
|
556
|
+
next.failed = { error };
|
|
764
557
|
});
|
|
765
558
|
}
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
return
|
|
559
|
+
|
|
560
|
+
//#endregion
|
|
561
|
+
//#region src/style/claim.ts
|
|
562
|
+
const tickets = /* @__PURE__ */ new WeakMap();
|
|
563
|
+
function componentProps(type, props, appearance) {
|
|
564
|
+
const context = appearance?.context;
|
|
565
|
+
if (!context || typeof type != "function") return {
|
|
566
|
+
appearance,
|
|
567
|
+
props
|
|
568
|
+
};
|
|
569
|
+
const value = context.resolve(props);
|
|
570
|
+
const entries = appearance.entries;
|
|
571
|
+
if (!value) return {
|
|
572
|
+
appearance: { entries },
|
|
573
|
+
props
|
|
574
|
+
};
|
|
575
|
+
return {
|
|
576
|
+
appearance: {
|
|
577
|
+
context: value.context,
|
|
578
|
+
entries
|
|
579
|
+
},
|
|
580
|
+
props: {
|
|
581
|
+
...props,
|
|
582
|
+
style: [createAppearanceToken(value), props.style]
|
|
583
|
+
}
|
|
584
|
+
};
|
|
773
585
|
}
|
|
774
|
-
function
|
|
775
|
-
const
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
const fiber = {
|
|
780
|
-
kind: "element",
|
|
781
|
-
key: value.key,
|
|
782
|
-
type: tag,
|
|
783
|
-
props: {},
|
|
784
|
-
context,
|
|
785
|
-
boundary,
|
|
786
|
-
start: element,
|
|
787
|
-
end: element,
|
|
788
|
-
children: [],
|
|
789
|
-
events: /* @__PURE__ */ new Map()
|
|
586
|
+
function door(value) {
|
|
587
|
+
const collected = {
|
|
588
|
+
classes: [],
|
|
589
|
+
declarations: {},
|
|
590
|
+
tokens: []
|
|
790
591
|
};
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
592
|
+
const { classes, declarations, tokens } = collected;
|
|
593
|
+
collect(value, collected, 1);
|
|
594
|
+
if (!classes.length && !tokens.length && !Object.keys(declarations).length) return void 0;
|
|
595
|
+
const key = Object.freeze({});
|
|
596
|
+
tickets.set(key, {
|
|
597
|
+
classes,
|
|
598
|
+
tokens
|
|
599
|
+
});
|
|
600
|
+
return Object.freeze({
|
|
601
|
+
...declarations,
|
|
602
|
+
[Symbol("style")]: key
|
|
794
603
|
});
|
|
795
|
-
if (value.props.autofocus || value.props.autoFocus) focusing.push(element);
|
|
796
|
-
return fiber;
|
|
797
604
|
}
|
|
798
|
-
function
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
605
|
+
function claim(element, appearance, resolved, className, value) {
|
|
606
|
+
const collected = {
|
|
607
|
+
classes: [],
|
|
608
|
+
declarations: {},
|
|
609
|
+
tokens: []
|
|
610
|
+
};
|
|
611
|
+
const entries = appearance?.entries || [];
|
|
612
|
+
let context = appearance?.context;
|
|
613
|
+
let reach = -1;
|
|
614
|
+
if (resolved) collect(createAppearanceToken(resolved), collected, 0);
|
|
615
|
+
appendClasses(collected.classes, className);
|
|
616
|
+
collect(value, collected, 0);
|
|
617
|
+
for (let index = entries.length - 1; index >= 0; index--) collect(entries[index].style, collected, entries[index].hops);
|
|
618
|
+
for (const { appearance, doors } of collected.tokens) {
|
|
619
|
+
for (const block of appearance.blocks || []) collected.classes.push(emitClass(block, doors, element.ownerDocument));
|
|
620
|
+
if (appearance.classes) collected.classes.push(...appearance.classes);
|
|
621
|
+
if (appearance.context && doors >= reach) {
|
|
622
|
+
context = appearance.context;
|
|
623
|
+
reach = doors;
|
|
806
624
|
}
|
|
807
625
|
}
|
|
626
|
+
return {
|
|
627
|
+
className: [...new Set(collected.classes)].join(" "),
|
|
628
|
+
context,
|
|
629
|
+
declarations: collected.declarations
|
|
630
|
+
};
|
|
808
631
|
}
|
|
809
|
-
function
|
|
810
|
-
|
|
632
|
+
function applyClaim(element, before, after) {
|
|
633
|
+
const previous = before || {
|
|
634
|
+
className: "",
|
|
635
|
+
declarations: {}
|
|
636
|
+
};
|
|
637
|
+
if (previous.className !== after.className) if (after.className) element.setAttribute("class", after.className);
|
|
638
|
+
else element.removeAttribute("class");
|
|
639
|
+
applyDeclarations(element.style, after.declarations, previous.declarations);
|
|
811
640
|
}
|
|
812
|
-
function
|
|
813
|
-
|
|
814
|
-
const
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
641
|
+
function collect(value, collected, doors) {
|
|
642
|
+
if (!value) return;
|
|
643
|
+
const token = appearanceToken(value);
|
|
644
|
+
if (token) {
|
|
645
|
+
collected.tokens.push({
|
|
646
|
+
appearance: token,
|
|
647
|
+
doors
|
|
648
|
+
});
|
|
649
|
+
Object.assign(collected.declarations, token.declarations);
|
|
650
|
+
return;
|
|
651
|
+
}
|
|
652
|
+
if (typeof value == "string") {
|
|
653
|
+
appendClasses(collected.classes, value);
|
|
654
|
+
return;
|
|
655
|
+
}
|
|
656
|
+
if (Array.isArray(value)) {
|
|
657
|
+
value.forEach((entry) => collect(entry, collected, doors));
|
|
658
|
+
return;
|
|
659
|
+
}
|
|
660
|
+
for (const symbol of Object.getOwnPropertySymbols(value)) {
|
|
661
|
+
const ticket = tickets.get(value[symbol]);
|
|
662
|
+
if (!ticket) continue;
|
|
663
|
+
collected.classes.push(...ticket.classes);
|
|
664
|
+
for (const carried of ticket.tokens) collected.tokens.push({
|
|
665
|
+
appearance: carried.appearance,
|
|
666
|
+
doors: carried.doors + doors
|
|
667
|
+
});
|
|
839
668
|
}
|
|
669
|
+
for (const key of Object.keys(value)) collected.declarations[key] = value[key];
|
|
670
|
+
}
|
|
671
|
+
function appendClasses(classes, value) {
|
|
672
|
+
if (typeof value == "string") classes.push(...value.split(/\s+/).filter(Boolean));
|
|
840
673
|
}
|
|
674
|
+
|
|
675
|
+
//#endregion
|
|
676
|
+
//#region src/render/style.ts
|
|
677
|
+
let rendering;
|
|
678
|
+
let touched = false;
|
|
679
|
+
const observed = /* @__PURE__ */ new WeakMap();
|
|
841
680
|
function observe(props) {
|
|
842
681
|
if (!("style" in props)) return props;
|
|
843
682
|
let output = observed.get(props);
|
|
@@ -860,25 +699,6 @@ function observe(props) {
|
|
|
860
699
|
}
|
|
861
700
|
return output;
|
|
862
701
|
}
|
|
863
|
-
function door(value) {
|
|
864
|
-
const collected = {
|
|
865
|
-
classes: [],
|
|
866
|
-
declarations: {},
|
|
867
|
-
tokens: []
|
|
868
|
-
};
|
|
869
|
-
const { classes, declarations, tokens } = collected;
|
|
870
|
-
collect(value, collected, 1);
|
|
871
|
-
if (!classes.length && !tokens.length && !Object.keys(declarations).length) return void 0;
|
|
872
|
-
const key = Object.freeze({});
|
|
873
|
-
tickets.set(key, {
|
|
874
|
-
classes,
|
|
875
|
-
tokens
|
|
876
|
-
});
|
|
877
|
-
return Object.freeze({
|
|
878
|
-
...declarations,
|
|
879
|
-
[Symbol("style")]: key
|
|
880
|
-
});
|
|
881
|
-
}
|
|
882
702
|
function consume(fiber, render) {
|
|
883
703
|
const previous = rendering;
|
|
884
704
|
const read = touched;
|
|
@@ -893,136 +713,250 @@ function consume(fiber, render) {
|
|
|
893
713
|
touched = read;
|
|
894
714
|
}
|
|
895
715
|
}
|
|
896
|
-
function
|
|
897
|
-
if (fiber.
|
|
898
|
-
|
|
899
|
-
(
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
const
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
}
|
|
909
|
-
function settle() {
|
|
910
|
-
if (settling) return;
|
|
911
|
-
settling = true;
|
|
912
|
-
try {
|
|
913
|
-
for (const boundary of dirty) {
|
|
914
|
-
dirty.delete(boundary);
|
|
915
|
-
const owner = boundary.owner;
|
|
916
|
-
const waiting = boundary.waiting.size > 0;
|
|
917
|
-
if (!owner.dead && waiting != !!owner.stash) waiting ? hide(owner, boundary) : reveal(owner);
|
|
918
|
-
}
|
|
919
|
-
} finally {
|
|
920
|
-
settling = false;
|
|
921
|
-
}
|
|
922
|
-
}
|
|
923
|
-
function hide(owner, boundary) {
|
|
924
|
-
const stash = document.createDocumentFragment();
|
|
925
|
-
for (const child of owner.children) move(child, stash, null);
|
|
926
|
-
owner.portals = portals(owner, []).map((portal) => {
|
|
927
|
-
const content = document.createDocumentFragment();
|
|
928
|
-
moveRange(portal.portalStart, portal.portalEnd, content);
|
|
929
|
-
return [portal, content];
|
|
716
|
+
function renderedAppearance(fiber) {
|
|
717
|
+
if (fiber.kind != "component" && fiber.kind != "function") return fiber.appearance;
|
|
718
|
+
const style = fiber.props?.style;
|
|
719
|
+
const entries = (fiber.appearance?.entries || []).map(({ hops, style }) => ({
|
|
720
|
+
hops: hops + 1,
|
|
721
|
+
style
|
|
722
|
+
}));
|
|
723
|
+
const inherited = fiber.appearance?.context || appearanceRoot();
|
|
724
|
+
const context = enterAppearance(inherited, latest(fiber.type));
|
|
725
|
+
if (context?.base && context !== inherited) entries.push({
|
|
726
|
+
hops: 0,
|
|
727
|
+
style: context.base
|
|
930
728
|
});
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
729
|
+
if (style && !fiber.consumed && !(fiber.instance && "style" in fiber.instance)) entries.push({
|
|
730
|
+
hops: 0,
|
|
731
|
+
style
|
|
732
|
+
});
|
|
733
|
+
return entries.length || context ? {
|
|
734
|
+
context,
|
|
735
|
+
entries
|
|
736
|
+
} : void 0;
|
|
937
737
|
}
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
738
|
+
|
|
739
|
+
//#endregion
|
|
740
|
+
//#region src/render/element.ts
|
|
741
|
+
const SVG = "http://www.w3.org/2000/svg";
|
|
742
|
+
const CONTROLS = ["checked", "value"];
|
|
743
|
+
const ENUMERATED = [
|
|
744
|
+
"contentEditable",
|
|
745
|
+
"contenteditable",
|
|
746
|
+
"draggable",
|
|
747
|
+
"spellcheck"
|
|
748
|
+
];
|
|
749
|
+
const ALIASES = {
|
|
750
|
+
autoFocus: "autofocus",
|
|
751
|
+
contentEditable: "contenteditable",
|
|
752
|
+
htmlFor: "for"
|
|
753
|
+
};
|
|
754
|
+
const controlled = /* @__PURE__ */ new WeakMap();
|
|
755
|
+
const restoring = /* @__PURE__ */ new WeakSet();
|
|
756
|
+
function mountElement(value, parent, before, context, boundary, appearance) {
|
|
757
|
+
const tag = value.type;
|
|
758
|
+
const host = hostOf(parent);
|
|
759
|
+
const element = (tag == "svg" || host instanceof SVGElement && host.localName != "foreignObject" ? SVG : void 0) ? document.createElementNS(SVG, tag) : document.createElement(tag);
|
|
760
|
+
const fiber = {
|
|
761
|
+
kind: "element",
|
|
762
|
+
key: value.key,
|
|
763
|
+
type: tag,
|
|
764
|
+
props: {},
|
|
765
|
+
context,
|
|
766
|
+
boundary,
|
|
767
|
+
start: element,
|
|
768
|
+
end: element,
|
|
769
|
+
children: [],
|
|
770
|
+
events: /* @__PURE__ */ new Map()
|
|
771
|
+
};
|
|
772
|
+
parent.insertBefore(element, before);
|
|
773
|
+
complete(fiber, () => {
|
|
774
|
+
patchProps(fiber, value.props, appearance);
|
|
775
|
+
});
|
|
776
|
+
if (value.props.autofocus || value.props.autoFocus) focusing.push(element);
|
|
777
|
+
return fiber;
|
|
945
778
|
}
|
|
946
|
-
function
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
779
|
+
function patchProps(fiber, next, appearance) {
|
|
780
|
+
const element = fiber.start;
|
|
781
|
+
const previous = fiber.props;
|
|
782
|
+
const raw = "dangerouslySetInnerHTML" in next;
|
|
783
|
+
const resolved = appearance?.context?.resolve(next, fiber.type);
|
|
784
|
+
if (raw) {
|
|
785
|
+
for (let index = fiber.children.length - 1; index >= 0; index--) unmountFiber(fiber.children[index]);
|
|
786
|
+
fiber.children = [];
|
|
950
787
|
}
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
if (node === end) break;
|
|
959
|
-
node = next;
|
|
788
|
+
for (const key of Object.keys({
|
|
789
|
+
...previous,
|
|
790
|
+
...next
|
|
791
|
+
})) {
|
|
792
|
+
if (key.startsWith("_") || key == "children" || key == "className" || key == "key" || key == "ref" || key == "style" || CONTROLS.includes(key)) continue;
|
|
793
|
+
if (previous[key] === next[key]) continue;
|
|
794
|
+
patchProp(fiber, element, key, previous[key], next[key]);
|
|
960
795
|
}
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
796
|
+
const claimed = claim(element, appearance, resolved, next.className, next.style);
|
|
797
|
+
applyClaim(element, fiber.claimed, claimed);
|
|
798
|
+
fiber.claimed = claimed;
|
|
799
|
+
fiber.props = next;
|
|
800
|
+
fiber.appearance = appearance;
|
|
801
|
+
if (!raw) reconcileChildren(fiber, element, null, next.children, fiber.context, fiber.boundary, claimed.context ? {
|
|
802
|
+
context: claimed.context,
|
|
803
|
+
entries: []
|
|
804
|
+
} : void 0);
|
|
805
|
+
for (const key of CONTROLS) {
|
|
806
|
+
const value = next[key];
|
|
807
|
+
const live = element[key];
|
|
808
|
+
if (value == null || !(key in element) ? previous[key] !== value : key == "value" ? String(live) !== String(value) : live !== value) patchProp(fiber, element, key, previous[key], value);
|
|
809
|
+
}
|
|
810
|
+
if (CONTROLS.some((key) => next[key] != null)) {
|
|
811
|
+
const document = element.ownerDocument;
|
|
812
|
+
controlled.set(element, fiber);
|
|
813
|
+
if (!restoring.has(document)) {
|
|
814
|
+
restoring.add(document);
|
|
815
|
+
document.addEventListener("input", restoreTarget);
|
|
816
|
+
document.addEventListener("change", restoreTarget);
|
|
969
817
|
}
|
|
970
|
-
holding = void 0;
|
|
971
|
-
if (!passive) wait(fiber, boundary);
|
|
972
|
-
const scope = fiber.scope;
|
|
973
|
-
let held = scope.holds;
|
|
974
|
-
scope.holds = void 0;
|
|
975
|
-
const clear = () => {
|
|
976
|
-
fiber.suspended.delete(clear);
|
|
977
|
-
release(held);
|
|
978
|
-
held = void 0;
|
|
979
|
-
};
|
|
980
|
-
(fiber.suspended ||= /* @__PURE__ */ new Set()).add(clear);
|
|
981
|
-
const resume = (retry) => {
|
|
982
|
-
fiber.suspended.delete(clear);
|
|
983
|
-
if (!scope.active) return clear();
|
|
984
|
-
if (held) (scope.holds ||= []).push(...held);
|
|
985
|
-
held = void 0;
|
|
986
|
-
retry();
|
|
987
|
-
};
|
|
988
|
-
thrown.then(() => resume(() => passive ? transition(() => schedule(scope)) : schedule(scope)), (error) => resume(() => pass(() => recover(fiber, error, fiber.boundary))));
|
|
989
|
-
return thrown;
|
|
990
818
|
}
|
|
991
|
-
|
|
819
|
+
if (previous.ref !== next.ref) patchProp(fiber, element, "ref", previous.ref, next.ref);
|
|
992
820
|
}
|
|
993
|
-
function
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
821
|
+
function patchProp(fiber, element, key, previous, next) {
|
|
822
|
+
if (key == "ref") {
|
|
823
|
+
applyRef(previous, null);
|
|
824
|
+
inserted(fiber, () => applyRef(next, element));
|
|
825
|
+
return;
|
|
826
|
+
}
|
|
827
|
+
if (key == "dangerouslySetInnerHTML") {
|
|
828
|
+
element.innerHTML = next?.__html || "";
|
|
829
|
+
return;
|
|
830
|
+
}
|
|
831
|
+
if (/^on[A-Z]/.test(key)) {
|
|
832
|
+
const capture = key.endsWith("Capture");
|
|
833
|
+
const lower = (capture ? key.slice(2, -7) : key.slice(2)).toLowerCase();
|
|
834
|
+
const name = lower == "doubleclick" ? "dblclick" : lower;
|
|
835
|
+
const id = `${name}:${capture}`;
|
|
836
|
+
const current = fiber.events.get(id);
|
|
837
|
+
if (current) element.removeEventListener(name, current, capture);
|
|
838
|
+
if (typeof next == "function") {
|
|
839
|
+
fiber.events.set(id, next);
|
|
840
|
+
element.addEventListener(name, next, capture);
|
|
841
|
+
} else fiber.events.delete(id);
|
|
842
|
+
return;
|
|
843
|
+
}
|
|
844
|
+
const name = ALIASES[key] || key;
|
|
845
|
+
if ((key.startsWith("aria-") || key.startsWith("data-") || ENUMERATED.includes(key)) && next != null) {
|
|
846
|
+
element.setAttribute(name, String(next));
|
|
847
|
+
return;
|
|
848
|
+
}
|
|
849
|
+
if (next === null || next === void 0 || next === false) {
|
|
850
|
+
if (key in element && typeof element[key] != "function") try {
|
|
851
|
+
const current = element[key];
|
|
852
|
+
element[key] = typeof current == "boolean" ? false : typeof current == "number" ? 0 : "";
|
|
853
|
+
} catch {}
|
|
854
|
+
element.removeAttribute(element.namespaceURI === SVG ? name.toLowerCase() : name);
|
|
855
|
+
element.removeAttribute(name);
|
|
856
|
+
return;
|
|
857
|
+
}
|
|
858
|
+
if (key in element && (element.namespaceURI !== SVG || settable(element, key))) try {
|
|
859
|
+
element[key] = next;
|
|
860
|
+
return;
|
|
861
|
+
} catch {}
|
|
862
|
+
element.setAttribute(name, next === true ? "" : String(next));
|
|
1010
863
|
}
|
|
1011
|
-
function
|
|
1012
|
-
|
|
864
|
+
function restoreTarget(event) {
|
|
865
|
+
const element = event.target;
|
|
866
|
+
const fiber = controlled.get(element);
|
|
867
|
+
if (fiber && event.type == settles(fiber.props, element)) queueMicrotask(() => afterFlush(() => restore(fiber)));
|
|
1013
868
|
}
|
|
1014
|
-
function
|
|
1015
|
-
|
|
1016
|
-
if (
|
|
1017
|
-
|
|
869
|
+
function settles(props, element) {
|
|
870
|
+
if (props.onInput) return "input";
|
|
871
|
+
if (props.onChange) return "change";
|
|
872
|
+
return element.type == "checkbox" || element.type == "radio" || element.localName == "select" ? "change" : "input";
|
|
1018
873
|
}
|
|
1019
|
-
function
|
|
1020
|
-
|
|
874
|
+
function restore(fiber) {
|
|
875
|
+
const element = fiber.start;
|
|
876
|
+
for (const key of CONTROLS) {
|
|
877
|
+
const value = fiber.props[key];
|
|
878
|
+
if (value == null || fiber.dead) continue;
|
|
879
|
+
if (key == "value" ? String(element.value) !== String(value) : element[key] !== value) element[key] = value;
|
|
880
|
+
}
|
|
1021
881
|
}
|
|
1022
|
-
function
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
882
|
+
function settable(element, key) {
|
|
883
|
+
let target = element;
|
|
884
|
+
let descriptor;
|
|
885
|
+
while (!(descriptor = Object.getOwnPropertyDescriptor(target, key))) target = Object.getPrototypeOf(target);
|
|
886
|
+
return !!(descriptor.set || descriptor.writable);
|
|
887
|
+
}
|
|
888
|
+
function applyRef(ref, value) {
|
|
889
|
+
if (typeof ref == "function") ref(value);
|
|
890
|
+
else if (ref && typeof ref == "object" && "current" in ref) ref.current = value;
|
|
891
|
+
}
|
|
892
|
+
function unmountElement(fiber) {
|
|
893
|
+
applyRef(fiber.props?.ref, null);
|
|
894
|
+
for (const [id, listener] of fiber.events) {
|
|
895
|
+
const [name, capture] = id.split(":");
|
|
896
|
+
fiber.start.removeEventListener(name, listener, capture === "true");
|
|
897
|
+
}
|
|
898
|
+
}
|
|
899
|
+
|
|
900
|
+
//#endregion
|
|
901
|
+
//#region src/render/portal.ts
|
|
902
|
+
function mountPortal(value, parent, before, context, boundary, appearance) {
|
|
903
|
+
const marker = document.createComment("portal");
|
|
904
|
+
const container = target(value.props.into, parent);
|
|
905
|
+
const portalStart = document.createComment("portal-root");
|
|
906
|
+
const portalEnd = document.createComment("/portal-root");
|
|
907
|
+
parent.insertBefore(marker, before);
|
|
908
|
+
container.append(portalStart, portalEnd);
|
|
909
|
+
const output = {
|
|
910
|
+
kind: "portal",
|
|
911
|
+
key: value.key,
|
|
912
|
+
type: PORTAL,
|
|
913
|
+
props: value.props,
|
|
914
|
+
context,
|
|
915
|
+
boundary,
|
|
916
|
+
appearance,
|
|
917
|
+
start: marker,
|
|
918
|
+
end: marker,
|
|
919
|
+
children: [],
|
|
920
|
+
portalContainer: container,
|
|
921
|
+
portalStart,
|
|
922
|
+
portalEnd
|
|
923
|
+
};
|
|
924
|
+
return complete(output, () => {
|
|
925
|
+
reconcilePortal(output, value.props.children, context, boundary, appearance);
|
|
926
|
+
});
|
|
927
|
+
}
|
|
928
|
+
function target(into, parent) {
|
|
929
|
+
if (typeof into != "string") return into;
|
|
930
|
+
const root = parent.getRootNode();
|
|
931
|
+
const found = [...document.querySelectorAll(into)];
|
|
932
|
+
if (root instanceof DocumentFragment) found.push(...root.querySelectorAll(into));
|
|
933
|
+
if (found.length != 1) throw new Error(`Portal target "${into}" ${found.length ? "is ambiguous" : "was not found"}.`);
|
|
934
|
+
return found[0];
|
|
935
|
+
}
|
|
936
|
+
function reconcilePortal(fiber, value, context, boundary, appearance) {
|
|
937
|
+
reconcileChildren(fiber, fiber.portalEnd.parentNode, fiber.portalEnd, value, context, boundary, appearance);
|
|
938
|
+
}
|
|
939
|
+
function patchPortal(fiber, value, context, appearance) {
|
|
940
|
+
fiber.appearance = appearance;
|
|
941
|
+
fiber.props = value.props;
|
|
942
|
+
reconcilePortal(fiber, value.props.children, context, fiber.boundary, appearance);
|
|
943
|
+
}
|
|
944
|
+
function unmountPortal(fiber) {
|
|
945
|
+
fiber.portalStart.remove();
|
|
946
|
+
fiber.portalEnd.remove();
|
|
947
|
+
}
|
|
948
|
+
|
|
949
|
+
//#endregion
|
|
950
|
+
//#region src/render/reconcile.ts
|
|
951
|
+
function reconcile(fiber, value, context, boundary, appearance) {
|
|
952
|
+
const detached = fiber.stash || fiber.staging;
|
|
953
|
+
if (detached) reconcileChildren(fiber, detached, null, value, context, boundary, appearance);
|
|
954
|
+
else reconcileChildren(fiber, fiber.end.parentNode, fiber.end, value, context, boundary, appearance);
|
|
955
|
+
}
|
|
956
|
+
function reconcileChildren(owner, parent, before, value, context, boundary, appearance) {
|
|
957
|
+
const values = childrenOf(value);
|
|
958
|
+
const old = owner.children;
|
|
959
|
+
const keyed = /* @__PURE__ */ new Map();
|
|
1026
960
|
const used = /* @__PURE__ */ new Set();
|
|
1027
961
|
const next = [];
|
|
1028
962
|
for (const child of old) if (child.key !== null && child.key !== void 0) keyed.set(child.key, child);
|
|
@@ -1038,11 +972,7 @@ function reconcileChildren(owner, parent, before, value, context, boundary, appe
|
|
|
1038
972
|
next.push(fiber);
|
|
1039
973
|
}
|
|
1040
974
|
} catch (error) {
|
|
1041
|
-
|
|
1042
|
-
for (const fiber of next) if (!old.includes(fiber)) park(fiber);
|
|
1043
|
-
if (holding.fiber) next.push(holding.fiber);
|
|
1044
|
-
holding.fiber = void 0;
|
|
1045
|
-
}
|
|
975
|
+
gather(error, next, old);
|
|
1046
976
|
owner.children = [...next, ...old.filter((child) => !child.dead && !next.includes(child))];
|
|
1047
977
|
throw error;
|
|
1048
978
|
}
|
|
@@ -1061,62 +991,15 @@ function patch(old, value, parent, before, context, boundary, appearance) {
|
|
|
1061
991
|
if (!old || !compatible(old, value)) return mount(value, parent, old?.start || before, context, boundary, appearance);
|
|
1062
992
|
if (old.ownBoundary) old.ownBoundary.parent = boundary;
|
|
1063
993
|
old.boundary = old.ownBoundary || boundary;
|
|
1064
|
-
if (old.kind == "collection")
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
if (old.kind == "text") {
|
|
1072
|
-
const next = String(value);
|
|
1073
|
-
if (old.start.nodeValue !== next) old.start.nodeValue = next;
|
|
1074
|
-
old.value = value;
|
|
1075
|
-
} else if (old.kind == "element") patchProps(old, value.props, appearance);
|
|
1076
|
-
else if (old.kind == "fragment") {
|
|
1077
|
-
old.context = context;
|
|
1078
|
-
old.appearance = appearance;
|
|
1079
|
-
reconcile(old, value.props.children, context, old.boundary, appearance);
|
|
1080
|
-
} else if (old.kind == "function") {
|
|
1081
|
-
const vnode = value;
|
|
1082
|
-
const resolved = componentProps(vnode.type, vnode.props, appearance);
|
|
1083
|
-
if (old.type !== vnode.type) {
|
|
1084
|
-
untrack(old.type, old.scope);
|
|
1085
|
-
old.type = vnode.type;
|
|
1086
|
-
old.scope.hot = true;
|
|
1087
|
-
track(old.type, old.scope);
|
|
1088
|
-
}
|
|
1089
|
-
old.appearance = resolved.appearance;
|
|
1090
|
-
old.props = observe(resolved.props);
|
|
1091
|
-
rerun(old, () => runFunction(old, passiveRender));
|
|
1092
|
-
} else if (old.kind == "component") {
|
|
1093
|
-
const resolved = isVNode(value) ? componentProps(value.type, value.props, appearance) : {
|
|
1094
|
-
appearance,
|
|
1095
|
-
props: old.props
|
|
1096
|
-
};
|
|
1097
|
-
old.appearance = resolved.appearance;
|
|
1098
|
-
const props = isVNode(value) ? observe(resolved.props) : resolved.props;
|
|
1099
|
-
if (isVNode(value) && props !== old.props) {
|
|
1100
|
-
const instance = old.instance;
|
|
1101
|
-
if (passiveRender) old.applied = true;
|
|
1102
|
-
if (instance instanceof Component) instance.props = props;
|
|
1103
|
-
else instance.set(merge(old.props, props));
|
|
1104
|
-
}
|
|
1105
|
-
old.props = props;
|
|
1106
|
-
rerun(old, () => runComponent(old, passiveRender));
|
|
1107
|
-
} else {
|
|
1108
|
-
old.appearance = appearance;
|
|
1109
|
-
const vnode = value;
|
|
1110
|
-
old.props = vnode.props;
|
|
1111
|
-
reconcilePortal(old, vnode.props.children, context, old.boundary, appearance);
|
|
1112
|
-
}
|
|
994
|
+
if (old.kind == "collection") patchCollection(old, appearance);
|
|
995
|
+
else if (old.kind == "text") patchText(old, value);
|
|
996
|
+
else if (old.kind == "element") patchProps(old, value.props, appearance);
|
|
997
|
+
else if (old.kind == "fragment") patchFragment(old, value, context, appearance);
|
|
998
|
+
else if (old.kind == "function") patchFunction(old, value, appearance);
|
|
999
|
+
else if (old.kind == "component") patchComponent(old, value, appearance);
|
|
1000
|
+
else patchPortal(old, value, context, appearance);
|
|
1113
1001
|
return old;
|
|
1114
1002
|
}
|
|
1115
|
-
function rerun(fiber, run) {
|
|
1116
|
-
claim$1(fiber.scope);
|
|
1117
|
-
run();
|
|
1118
|
-
settle$1(fiber.scope);
|
|
1119
|
-
}
|
|
1120
1003
|
function compatible(fiber, value) {
|
|
1121
1004
|
if (fiber.kind == "text") return [
|
|
1122
1005
|
"string",
|
|
@@ -1131,241 +1014,352 @@ function compatible(fiber, value) {
|
|
|
1131
1014
|
return true;
|
|
1132
1015
|
}
|
|
1133
1016
|
function source(value) {
|
|
1134
|
-
if (value instanceof
|
|
1017
|
+
if (value instanceof Model) return value.is;
|
|
1135
1018
|
while (isCollection(value) && isCollection(Object.getPrototypeOf(value))) value = Object.getPrototypeOf(value);
|
|
1136
1019
|
return value;
|
|
1137
1020
|
}
|
|
1138
|
-
function renderable(value) {
|
|
1139
|
-
return value instanceof State && typeof value.render == "function";
|
|
1140
|
-
}
|
|
1141
|
-
function merge(previous, next) {
|
|
1142
|
-
const output = {};
|
|
1143
|
-
for (const key in previous) output[key] = void 0;
|
|
1144
|
-
return {
|
|
1145
|
-
...output,
|
|
1146
|
-
...next
|
|
1147
|
-
};
|
|
1148
|
-
}
|
|
1149
|
-
function isCollection(value) {
|
|
1150
|
-
return value instanceof has.List || value instanceof has.Pool || value instanceof map.Managed;
|
|
1151
|
-
}
|
|
1152
1021
|
function keyOf(value) {
|
|
1153
1022
|
if (renderable(value)) return value.key;
|
|
1154
1023
|
return isVNode(value) ? value.key : void 0;
|
|
1155
1024
|
}
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1025
|
+
|
|
1026
|
+
//#endregion
|
|
1027
|
+
//#region src/render/suspense.ts
|
|
1028
|
+
const dirty = /* @__PURE__ */ new Set();
|
|
1029
|
+
const stashes = /* @__PURE__ */ new WeakMap();
|
|
1030
|
+
let holding;
|
|
1031
|
+
let settling = false;
|
|
1032
|
+
function park(fiber) {
|
|
1033
|
+
move(fiber, fragment(), null);
|
|
1165
1034
|
}
|
|
1166
|
-
function
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
fiber.
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
if (
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
|
|
1035
|
+
function hold(fiber, error) {
|
|
1036
|
+
if (!holding || error !== holding.thrown) return false;
|
|
1037
|
+
park(fiber);
|
|
1038
|
+
holding.fiber = fiber;
|
|
1039
|
+
return true;
|
|
1040
|
+
}
|
|
1041
|
+
function gather(error, next, old) {
|
|
1042
|
+
if (!holding || error !== holding.thrown) return;
|
|
1043
|
+
for (const fiber of next) if (!old.includes(fiber)) park(fiber);
|
|
1044
|
+
if (holding.fiber) next.push(holding.fiber);
|
|
1045
|
+
holding.fiber = void 0;
|
|
1046
|
+
}
|
|
1047
|
+
function hostOf(parent) {
|
|
1048
|
+
let host = parent;
|
|
1049
|
+
for (let owner = stashes.get(host); owner; owner = stashes.get(host)) host = owner.end.parentNode;
|
|
1050
|
+
return host;
|
|
1051
|
+
}
|
|
1052
|
+
function wait(fiber, boundary) {
|
|
1053
|
+
if (fiber.waitingOn !== boundary) unwait(fiber);
|
|
1054
|
+
fiber.waitingOn = boundary;
|
|
1055
|
+
(boundary.waiting ||= /* @__PURE__ */ new Set()).add(fiber);
|
|
1056
|
+
dirty.add(boundary);
|
|
1057
|
+
}
|
|
1058
|
+
function unwait(fiber) {
|
|
1059
|
+
const boundary = fiber.waitingOn;
|
|
1060
|
+
if (!boundary) return;
|
|
1061
|
+
fiber.waitingOn = void 0;
|
|
1062
|
+
boundary.waiting.delete(fiber);
|
|
1063
|
+
if (!boundary.owner.dead) dirty.add(boundary);
|
|
1064
|
+
}
|
|
1065
|
+
function settle() {
|
|
1066
|
+
if (settling) return;
|
|
1067
|
+
settling = true;
|
|
1068
|
+
try {
|
|
1069
|
+
for (const boundary of dirty) {
|
|
1070
|
+
dirty.delete(boundary);
|
|
1071
|
+
const owner = boundary.owner;
|
|
1072
|
+
const waiting = boundary.waiting.size > 0;
|
|
1073
|
+
if (!owner.dead && waiting != !!owner.stash) waiting ? hide(owner, boundary) : reveal(owner);
|
|
1204
1074
|
}
|
|
1075
|
+
} finally {
|
|
1076
|
+
settling = false;
|
|
1205
1077
|
}
|
|
1206
|
-
if (previous.ref !== next.ref) patchProp(fiber, element, "ref", previous.ref, next.ref);
|
|
1207
1078
|
}
|
|
1208
|
-
function
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
|
|
1079
|
+
function hide(owner, boundary) {
|
|
1080
|
+
const stash = document.createDocumentFragment();
|
|
1081
|
+
for (const child of owner.children) move(child, stash, null);
|
|
1082
|
+
owner.portals = portals(owner, []).map((portal) => {
|
|
1083
|
+
const content = document.createDocumentFragment();
|
|
1084
|
+
moveRange(portal.portalStart, portal.portalEnd, content);
|
|
1085
|
+
return [portal, content];
|
|
1086
|
+
});
|
|
1087
|
+
stashes.set(stash, owner);
|
|
1088
|
+
const context = owner.childContext;
|
|
1089
|
+
const placeholder = range("fragment", owner.end.parentNode, owner.end, context);
|
|
1090
|
+
owner.stash = stash;
|
|
1091
|
+
owner.placeholder = placeholder;
|
|
1092
|
+
reconcile(placeholder, boundary.fallback(), context, boundary.parent);
|
|
1093
|
+
}
|
|
1094
|
+
function reveal(owner) {
|
|
1095
|
+
unmountFiber(owner.placeholder);
|
|
1096
|
+
owner.end.parentNode.insertBefore(owner.stash, owner.end);
|
|
1097
|
+
for (const [portal, content] of owner.portals) if (!portal.dead) portal.portalContainer.append(content);
|
|
1098
|
+
owner.portals = void 0;
|
|
1099
|
+
owner.placeholder = void 0;
|
|
1100
|
+
owner.stash = void 0;
|
|
1101
|
+
}
|
|
1102
|
+
function portals(fiber, found) {
|
|
1103
|
+
for (const child of fiber.children) {
|
|
1104
|
+
if (child.kind == "portal") found.push(child);
|
|
1105
|
+
portals(child, found);
|
|
1230
1106
|
}
|
|
1231
|
-
|
|
1232
|
-
|
|
1233
|
-
|
|
1234
|
-
|
|
1107
|
+
return found;
|
|
1108
|
+
}
|
|
1109
|
+
function suspend(fiber, thrown, passive, empty) {
|
|
1110
|
+
const boundary = fiber.boundary;
|
|
1111
|
+
if (isThenable(thrown)) {
|
|
1112
|
+
if (!boundary) throw thrown;
|
|
1113
|
+
if (passive && empty && depth > 1) {
|
|
1114
|
+
if (holding?.thrown !== thrown) holding = { thrown };
|
|
1115
|
+
throw thrown;
|
|
1116
|
+
}
|
|
1117
|
+
holding = void 0;
|
|
1118
|
+
if (!passive) wait(fiber, boundary);
|
|
1119
|
+
const scope = fiber.scope;
|
|
1120
|
+
let held = scope.holds;
|
|
1121
|
+
scope.holds = void 0;
|
|
1122
|
+
const clear = () => {
|
|
1123
|
+
fiber.suspended.delete(clear);
|
|
1124
|
+
release(held);
|
|
1125
|
+
held = void 0;
|
|
1126
|
+
};
|
|
1127
|
+
(fiber.suspended ||= /* @__PURE__ */ new Set()).add(clear);
|
|
1128
|
+
const resume = (retry) => {
|
|
1129
|
+
fiber.suspended.delete(clear);
|
|
1130
|
+
if (!scope.active) return clear();
|
|
1131
|
+
if (held) (scope.holds ||= []).push(...held);
|
|
1132
|
+
held = void 0;
|
|
1133
|
+
retry();
|
|
1134
|
+
};
|
|
1135
|
+
thrown.then(() => resume(() => passive ? transition(() => schedule(scope)) : schedule(scope)), (error) => resume(() => pass(() => recover(fiber, error, fiber.boundary))));
|
|
1136
|
+
return thrown;
|
|
1235
1137
|
}
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1138
|
+
recover(fiber, thrown, fiber.boundary);
|
|
1139
|
+
}
|
|
1140
|
+
function recover(fiber, thrown, boundary) {
|
|
1141
|
+
const error = thrown instanceof Error ? thrown : new Error(String(thrown));
|
|
1142
|
+
while (boundary && !boundary.catch) boundary = boundary.parent;
|
|
1143
|
+
if (!boundary) throw error;
|
|
1144
|
+
const handler = boundary;
|
|
1145
|
+
const token = {};
|
|
1146
|
+
wait(fiber, handler);
|
|
1147
|
+
fiber.recovering = token;
|
|
1148
|
+
Promise.resolve(handler.catch(error)).then(() => {
|
|
1149
|
+
if (fiber.recovering !== token) return;
|
|
1150
|
+
fiber.recovering = void 0;
|
|
1151
|
+
if (!fiber.scope.active || fiber.retried) return;
|
|
1152
|
+
fiber.retried = true;
|
|
1153
|
+
schedule(fiber.scope);
|
|
1154
|
+
}, (next) => {
|
|
1155
|
+
if (fiber.recovering === token && fiber.scope.active) pass(() => recover(fiber, next, handler.parent));
|
|
1156
|
+
});
|
|
1157
|
+
}
|
|
1158
|
+
function isThenable(value) {
|
|
1159
|
+
return !!value && typeof value.then == "function";
|
|
1160
|
+
}
|
|
1161
|
+
|
|
1162
|
+
//#endregion
|
|
1163
|
+
//#region src/render/component.ts
|
|
1164
|
+
function mountFunction(value, parent, before, context, boundary, appearance) {
|
|
1165
|
+
const fiber = range("function", parent, before, context);
|
|
1166
|
+
const resolved = componentProps(value.type, value.props, appearance);
|
|
1167
|
+
fiber.key = value.key;
|
|
1168
|
+
fiber.type = value.type;
|
|
1169
|
+
fiber.props = observe(resolved.props);
|
|
1170
|
+
fiber.boundary = boundary;
|
|
1171
|
+
fiber.appearance = resolved.appearance;
|
|
1172
|
+
fiber.scope = makeScope("function", context, (passive) => runFunction(fiber, passive));
|
|
1173
|
+
fiber.render = () => enter(fiber.scope, () => {
|
|
1174
|
+
const type = latest(fiber.type);
|
|
1175
|
+
return resolve(type, fiber.props, () => call(type, fiber.props));
|
|
1176
|
+
});
|
|
1177
|
+
track(fiber.type, fiber.scope);
|
|
1178
|
+
probing(fiber);
|
|
1179
|
+
return complete(fiber, () => {
|
|
1180
|
+
runFunction(fiber, passiveRender);
|
|
1181
|
+
});
|
|
1182
|
+
}
|
|
1183
|
+
function mountOwnedComponent(value, parent, before, context, boundary, appearance) {
|
|
1184
|
+
const resolved = componentProps(value.type, value.props, appearance);
|
|
1185
|
+
const Type = value.type;
|
|
1186
|
+
const props = observe(resolved.props);
|
|
1187
|
+
const instance = new Type(props, Type.prototype instanceof Component ? void 0 : () => props.is?.(instance));
|
|
1188
|
+
return mountComponent(instance, parent, before, context, boundary, resolved.appearance, true, value.key, props);
|
|
1189
|
+
}
|
|
1190
|
+
function mountComponent(instance, parent, before, context, inherited, appearance, owned = false, key, props = instance.props) {
|
|
1191
|
+
const fiber = range("component", parent, before, context);
|
|
1192
|
+
const childContext = context.push(instance);
|
|
1193
|
+
const element = owned ? props : {};
|
|
1194
|
+
const fallback = element.fallback !== void 0 ? element.fallback : instance.fallback;
|
|
1195
|
+
const ownBoundary = fallback !== void 0 && fallback !== false || element.catch || instance.catch ? {
|
|
1196
|
+
catch: element.catch || instance.catch ? (error) => {
|
|
1197
|
+
return (owned && fiber.props.catch || instance.catch).call(instance, error, instance);
|
|
1198
|
+
} : void 0,
|
|
1199
|
+
fallback: () => {
|
|
1200
|
+
const placed = owned ? fiber.props.fallback : void 0;
|
|
1201
|
+
return placed !== void 0 ? placed : instance.fallback;
|
|
1202
|
+
},
|
|
1203
|
+
owner: fiber,
|
|
1204
|
+
parent: inherited
|
|
1205
|
+
} : inherited;
|
|
1206
|
+
fiber.boundary = ownBoundary;
|
|
1207
|
+
if (ownBoundary !== inherited) fiber.ownBoundary = ownBoundary;
|
|
1208
|
+
fiber.childContext = childContext;
|
|
1209
|
+
fiber.instance = instance;
|
|
1210
|
+
fiber.key = owned ? key : instance.key;
|
|
1211
|
+
fiber.type = instance.constructor;
|
|
1212
|
+
fiber.props = props;
|
|
1213
|
+
fiber.owned = owned;
|
|
1214
|
+
fiber.appearance = appearance;
|
|
1215
|
+
fiber.scope = makeScope("component", childContext, (passive) => runComponent(fiber, passive));
|
|
1216
|
+
fiber.render = () => enter(fiber.scope, () => {
|
|
1217
|
+
const { render } = fiber.value;
|
|
1218
|
+
return render ? unbind(render).call(fiber.value, fiber.props) : fiber.props.children ?? null;
|
|
1219
|
+
});
|
|
1220
|
+
probing(fiber);
|
|
1221
|
+
let first = true;
|
|
1222
|
+
let proxy = instance;
|
|
1223
|
+
fiber.release = watch(instance, (current, events) => {
|
|
1224
|
+
const { applied, scope } = fiber;
|
|
1225
|
+
proxy = current;
|
|
1226
|
+
fiber.applied = void 0;
|
|
1227
|
+
if (!first && scope.active) if (applied && events.includes("props")) transition(() => schedule(scope));
|
|
1228
|
+
else schedule(scope);
|
|
1229
|
+
first = false;
|
|
1230
|
+
}, void 0, transition);
|
|
1231
|
+
Object.defineProperty(fiber, "value", { get: () => proxy });
|
|
1232
|
+
try {
|
|
1233
|
+
complete(fiber, () => {
|
|
1234
|
+
runComponent(fiber, passiveRender);
|
|
1235
|
+
});
|
|
1236
|
+
} finally {
|
|
1237
|
+
if (owned && !fiber.dead) inserted(fiber, () => fiber.cleanup = instance.mount?.());
|
|
1244
1238
|
}
|
|
1245
|
-
|
|
1246
|
-
element[key] = next;
|
|
1247
|
-
return;
|
|
1248
|
-
} catch {}
|
|
1249
|
-
element.setAttribute(name, next === true ? "" : String(next));
|
|
1239
|
+
return fiber;
|
|
1250
1240
|
}
|
|
1251
|
-
function
|
|
1252
|
-
const
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
};
|
|
1256
|
-
if (previous.className !== after.className) if (after.className) element.setAttribute("class", after.className);
|
|
1257
|
-
else element.removeAttribute("class");
|
|
1258
|
-
applyDeclarations(element.style, after.declarations, previous.declarations);
|
|
1241
|
+
function runFunction(fiber, passive) {
|
|
1242
|
+
const result = attempt(fiber, passive, fiber.render);
|
|
1243
|
+
if (result === true) inserted(fiber, () => commit(fiber.scope));
|
|
1244
|
+
else return result;
|
|
1259
1245
|
}
|
|
1260
|
-
function
|
|
1261
|
-
const
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
for (let index = entries.length - 1; index >= 0; index--) collect(entries[index].style, collected, entries[index].hops);
|
|
1273
|
-
for (const { appearance, doors } of collected.tokens) {
|
|
1274
|
-
for (const block of appearance.blocks || []) collected.classes.push(emitClass(block, doors, element.ownerDocument));
|
|
1275
|
-
if (appearance.classes) collected.classes.push(...appearance.classes);
|
|
1276
|
-
if (appearance.context && doors >= reach) {
|
|
1277
|
-
context = appearance.context;
|
|
1278
|
-
reach = doors;
|
|
1246
|
+
function runComponent(fiber, passive) {
|
|
1247
|
+
const result = attempt(fiber, passive, fiber.render);
|
|
1248
|
+
if (result !== true) return result;
|
|
1249
|
+
}
|
|
1250
|
+
function probing(fiber) {
|
|
1251
|
+
const scope = fiber.scope;
|
|
1252
|
+
scope.empty = () => !fiber.children.length;
|
|
1253
|
+
scope.probe = () => {
|
|
1254
|
+
try {
|
|
1255
|
+
scope.probed = { output: consume(fiber, fiber.render) };
|
|
1256
|
+
} catch (thrown) {
|
|
1257
|
+
if (isThenable(thrown)) return thrown;
|
|
1279
1258
|
}
|
|
1280
|
-
}
|
|
1281
|
-
return {
|
|
1282
|
-
className: [...new Set(collected.classes)].join(" "),
|
|
1283
|
-
context,
|
|
1284
|
-
declarations: collected.declarations
|
|
1285
1259
|
};
|
|
1286
1260
|
}
|
|
1287
|
-
function
|
|
1288
|
-
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
const inherited = fiber.appearance?.context || appearanceRoot();
|
|
1295
|
-
const context = enterAppearance(inherited, latest(fiber.type));
|
|
1296
|
-
if (context?.base && context !== inherited) entries.push({
|
|
1297
|
-
hops: 0,
|
|
1298
|
-
style: context.base
|
|
1299
|
-
});
|
|
1300
|
-
if (style && !fiber.consumed && !(fiber.instance && "style" in fiber.instance)) entries.push({
|
|
1301
|
-
hops: 0,
|
|
1302
|
-
style
|
|
1303
|
-
});
|
|
1304
|
-
return entries.length || context ? {
|
|
1305
|
-
context,
|
|
1306
|
-
entries
|
|
1307
|
-
} : void 0;
|
|
1308
|
-
}
|
|
1309
|
-
function collect(value, collected, doors) {
|
|
1310
|
-
if (!value) return;
|
|
1311
|
-
const token = appearanceToken(value);
|
|
1312
|
-
if (token) {
|
|
1313
|
-
collected.tokens.push({
|
|
1314
|
-
appearance: token,
|
|
1315
|
-
doors
|
|
1316
|
-
});
|
|
1317
|
-
Object.assign(collected.declarations, token.declarations);
|
|
1318
|
-
return;
|
|
1319
|
-
}
|
|
1320
|
-
if (typeof value == "string") {
|
|
1321
|
-
appendClasses(collected.classes, value);
|
|
1322
|
-
return;
|
|
1323
|
-
}
|
|
1324
|
-
if (Array.isArray(value)) {
|
|
1325
|
-
value.forEach((entry) => collect(entry, collected, doors));
|
|
1326
|
-
return;
|
|
1261
|
+
function patchFunction(fiber, value, appearance) {
|
|
1262
|
+
const resolved = componentProps(value.type, value.props, appearance);
|
|
1263
|
+
if (fiber.type !== value.type) {
|
|
1264
|
+
untrack(fiber.type, fiber.scope);
|
|
1265
|
+
fiber.type = value.type;
|
|
1266
|
+
fiber.scope.hot = true;
|
|
1267
|
+
track(fiber.type, fiber.scope);
|
|
1327
1268
|
}
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
|
|
1331
|
-
|
|
1332
|
-
|
|
1333
|
-
|
|
1334
|
-
|
|
1335
|
-
|
|
1269
|
+
fiber.appearance = resolved.appearance;
|
|
1270
|
+
fiber.props = observe(resolved.props);
|
|
1271
|
+
rerun(fiber, () => runFunction(fiber, passiveRender));
|
|
1272
|
+
}
|
|
1273
|
+
function patchComponent(fiber, value, appearance) {
|
|
1274
|
+
const resolved = isVNode(value) ? componentProps(value.type, value.props, appearance) : {
|
|
1275
|
+
appearance,
|
|
1276
|
+
props: fiber.props
|
|
1277
|
+
};
|
|
1278
|
+
fiber.appearance = resolved.appearance;
|
|
1279
|
+
const props = isVNode(value) ? observe(resolved.props) : resolved.props;
|
|
1280
|
+
if (isVNode(value) && props !== fiber.props) {
|
|
1281
|
+
const instance = fiber.instance;
|
|
1282
|
+
if (passiveRender) fiber.applied = true;
|
|
1283
|
+
if (instance instanceof Component) instance.props = props;
|
|
1284
|
+
else instance.set(merge(fiber.props, props));
|
|
1336
1285
|
}
|
|
1337
|
-
|
|
1286
|
+
fiber.props = props;
|
|
1287
|
+
rerun(fiber, () => runComponent(fiber, passiveRender));
|
|
1338
1288
|
}
|
|
1339
|
-
function
|
|
1340
|
-
|
|
1289
|
+
function rerun(fiber, run) {
|
|
1290
|
+
claim$1(fiber.scope);
|
|
1291
|
+
run();
|
|
1292
|
+
settle$1(fiber.scope);
|
|
1341
1293
|
}
|
|
1342
|
-
function
|
|
1343
|
-
|
|
1344
|
-
|
|
1345
|
-
if (fiber &&
|
|
1294
|
+
function unmountComponent(fiber) {
|
|
1295
|
+
if (typeof fiber.cleanup == "function") fiber.cleanup();
|
|
1296
|
+
fiber.childContext?.pop();
|
|
1297
|
+
if (fiber.owned && !fiber.instance.get(null)) fiber.instance.set(null);
|
|
1346
1298
|
}
|
|
1347
|
-
function
|
|
1348
|
-
|
|
1349
|
-
if (props.onChange) return "change";
|
|
1350
|
-
return element.type == "checkbox" || element.type == "radio" || element.localName == "select" ? "change" : "input";
|
|
1299
|
+
function renderable(value) {
|
|
1300
|
+
return value instanceof Model && typeof value.render == "function";
|
|
1351
1301
|
}
|
|
1352
|
-
function
|
|
1353
|
-
const
|
|
1354
|
-
for (const key
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
|
|
1302
|
+
function merge(previous, next) {
|
|
1303
|
+
const output = {};
|
|
1304
|
+
for (const key in previous) output[key] = void 0;
|
|
1305
|
+
return {
|
|
1306
|
+
...output,
|
|
1307
|
+
...next
|
|
1308
|
+
};
|
|
1309
|
+
}
|
|
1310
|
+
|
|
1311
|
+
//#endregion
|
|
1312
|
+
//#region src/render/mount.ts
|
|
1313
|
+
function complete(fiber, work) {
|
|
1314
|
+
try {
|
|
1315
|
+
work();
|
|
1316
|
+
} catch (error) {
|
|
1317
|
+
if (!hold(fiber, error)) unmountFiber(fiber);
|
|
1318
|
+
throw error;
|
|
1358
1319
|
}
|
|
1320
|
+
return fiber;
|
|
1359
1321
|
}
|
|
1360
|
-
function
|
|
1361
|
-
|
|
1362
|
-
|
|
1363
|
-
|
|
1364
|
-
|
|
1322
|
+
function mount(value, parent, before, context, boundary, appearance) {
|
|
1323
|
+
if (typeof value == "string" || typeof value == "number" || typeof value == "bigint") {
|
|
1324
|
+
const text = document.createTextNode(String(value));
|
|
1325
|
+
parent.insertBefore(text, before);
|
|
1326
|
+
return {
|
|
1327
|
+
kind: "text",
|
|
1328
|
+
value,
|
|
1329
|
+
context,
|
|
1330
|
+
start: text,
|
|
1331
|
+
end: text,
|
|
1332
|
+
children: []
|
|
1333
|
+
};
|
|
1334
|
+
}
|
|
1335
|
+
if (renderable(value)) return mountComponent(value, parent, before, context, boundary, appearance);
|
|
1336
|
+
if (isCollection(value)) return mountCollection(value, parent, before, context, boundary, appearance);
|
|
1337
|
+
if (!isVNode(value)) throw new TypeError(`Cannot render ${String(value)}.`);
|
|
1338
|
+
if (value.type === Fragment$1) return mountFragment(value, parent, before, context, boundary, appearance);
|
|
1339
|
+
if (value.type === PORTAL) return mountPortal(value, parent, before, context, boundary, appearance);
|
|
1340
|
+
if (typeof value.type == "string") return mountElement(value, parent, before, context, boundary, appearance);
|
|
1341
|
+
if (typeof value.type != "function") throw new Error(`Cannot render ${String(value.type)}.`);
|
|
1342
|
+
if (value.type.prototype instanceof Model) return mountOwnedComponent(value, parent, before, context, boundary, appearance);
|
|
1343
|
+
return mountFunction(value, parent, before, context, boundary, appearance);
|
|
1365
1344
|
}
|
|
1366
|
-
function
|
|
1367
|
-
|
|
1368
|
-
|
|
1345
|
+
function mountFragment(value, parent, before, context, boundary, appearance) {
|
|
1346
|
+
const fiber = range("fragment", parent, before, context);
|
|
1347
|
+
fiber.key = value.key;
|
|
1348
|
+
fiber.type = Fragment$1;
|
|
1349
|
+
fiber.appearance = appearance;
|
|
1350
|
+
return complete(fiber, () => {
|
|
1351
|
+
reconcile(fiber, value.props.children, context, boundary, appearance);
|
|
1352
|
+
});
|
|
1353
|
+
}
|
|
1354
|
+
function patchText(fiber, value) {
|
|
1355
|
+
const next = String(value);
|
|
1356
|
+
if (fiber.start.nodeValue !== next) fiber.start.nodeValue = next;
|
|
1357
|
+
fiber.value = value;
|
|
1358
|
+
}
|
|
1359
|
+
function patchFragment(fiber, value, context, appearance) {
|
|
1360
|
+
fiber.context = context;
|
|
1361
|
+
fiber.appearance = appearance;
|
|
1362
|
+
reconcile(fiber, value.props.children, context, fiber.boundary, appearance);
|
|
1369
1363
|
}
|
|
1370
1364
|
function unmountFiber(fiber) {
|
|
1371
1365
|
fiber.dead = true;
|
|
@@ -1376,30 +1370,88 @@ function unmountFiber(fiber) {
|
|
|
1376
1370
|
if (fiber.kind == "function") untrack(fiber.type, fiber.scope);
|
|
1377
1371
|
if (fiber.scope) dispose(fiber.scope);
|
|
1378
1372
|
fiber.release?.();
|
|
1379
|
-
if (fiber.kind == "element")
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
|
|
1384
|
-
|
|
1373
|
+
if (fiber.kind == "element") unmountElement(fiber);
|
|
1374
|
+
else if (fiber.kind == "component") unmountComponent(fiber);
|
|
1375
|
+
else if (fiber.kind == "portal") unmountPortal(fiber);
|
|
1376
|
+
removeRange(fiber.start, fiber.end);
|
|
1377
|
+
}
|
|
1378
|
+
|
|
1379
|
+
//#endregion
|
|
1380
|
+
//#region src/render/render.ts
|
|
1381
|
+
const roots = /* @__PURE__ */ new WeakMap();
|
|
1382
|
+
const focusing = [];
|
|
1383
|
+
let passiveRender = false;
|
|
1384
|
+
let depth = 0;
|
|
1385
|
+
function render(node, container) {
|
|
1386
|
+
roots.get(container)?.();
|
|
1387
|
+
container.replaceChildren();
|
|
1388
|
+
const context = new Context(Context.root);
|
|
1389
|
+
const fiber = range("fragment", container, null, context);
|
|
1390
|
+
try {
|
|
1391
|
+
pass(() => {
|
|
1392
|
+
const appearanceContext = appearanceRoot();
|
|
1393
|
+
reconcile(fiber, node, context, void 0, appearanceContext ? {
|
|
1394
|
+
context: appearanceContext,
|
|
1395
|
+
entries: []
|
|
1396
|
+
} : void 0);
|
|
1397
|
+
});
|
|
1398
|
+
} catch (error) {
|
|
1399
|
+
unmountFiber(fiber);
|
|
1400
|
+
context.pop();
|
|
1401
|
+
throw error;
|
|
1385
1402
|
}
|
|
1386
|
-
|
|
1387
|
-
|
|
1388
|
-
|
|
1389
|
-
|
|
1390
|
-
|
|
1391
|
-
|
|
1392
|
-
|
|
1403
|
+
let active = true;
|
|
1404
|
+
const unmount = () => {
|
|
1405
|
+
if (!active) return;
|
|
1406
|
+
active = false;
|
|
1407
|
+
unmountFiber(fiber);
|
|
1408
|
+
context.pop();
|
|
1409
|
+
roots.delete(container);
|
|
1410
|
+
};
|
|
1411
|
+
roots.set(container, unmount);
|
|
1412
|
+
return unmount;
|
|
1413
|
+
}
|
|
1414
|
+
function pass(work) {
|
|
1415
|
+
depth++;
|
|
1416
|
+
try {
|
|
1417
|
+
return work();
|
|
1418
|
+
} finally {
|
|
1419
|
+
if (!--depth) {
|
|
1420
|
+
settle();
|
|
1421
|
+
focus();
|
|
1422
|
+
}
|
|
1393
1423
|
}
|
|
1394
|
-
removeRange(fiber.start, fiber.end);
|
|
1395
1424
|
}
|
|
1396
|
-
function
|
|
1397
|
-
|
|
1398
|
-
|
|
1399
|
-
|
|
1400
|
-
|
|
1401
|
-
|
|
1402
|
-
|
|
1425
|
+
function focus() {
|
|
1426
|
+
for (const element of focusing.splice(0)) if (element.isConnected) element.focus();
|
|
1427
|
+
}
|
|
1428
|
+
function attempt(fiber, passive, render) {
|
|
1429
|
+
const previous = passiveRender;
|
|
1430
|
+
const scope = fiber.scope;
|
|
1431
|
+
const probed = scope.probed;
|
|
1432
|
+
const empty = !fiber.children.length;
|
|
1433
|
+
scope.probed = void 0;
|
|
1434
|
+
passiveRender ||= passive;
|
|
1435
|
+
if (passive && !depth && empty && !fiber.stash) fiber.staging ||= fragment();
|
|
1436
|
+
const run = () => pass(() => {
|
|
1437
|
+
try {
|
|
1438
|
+
reconcile(fiber, probed ? probed.output : consume(fiber, render), scope.childContext, fiber.boundary, renderedAppearance(fiber));
|
|
1439
|
+
if (fiber.staging) {
|
|
1440
|
+
fiber.end.parentNode.insertBefore(fiber.staging, fiber.end);
|
|
1441
|
+
attach(fiber.staging);
|
|
1442
|
+
fiber.staging = void 0;
|
|
1443
|
+
}
|
|
1444
|
+
if (!fiber.recovering) unwait(fiber);
|
|
1445
|
+
fiber.retried = void 0;
|
|
1446
|
+
return true;
|
|
1447
|
+
} catch (thrown) {
|
|
1448
|
+
return suspend(fiber, thrown, passive, empty);
|
|
1449
|
+
}
|
|
1450
|
+
});
|
|
1451
|
+
try {
|
|
1452
|
+
return passive ? batched(run) : run();
|
|
1453
|
+
} finally {
|
|
1454
|
+
passiveRender = previous;
|
|
1403
1455
|
}
|
|
1404
1456
|
}
|
|
1405
1457
|
|