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