kopular 0.13.0 → 0.14.1

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.
@@ -0,0 +1,95 @@
1
+ using "./dom";
2
+
3
+ // A lightweight, framework-owned description of one DOM element — Render()
4
+ // builds a tree of these instead of real DOM nodes, so Update() can DIFF
5
+ // the new tree against the previous one and patch only what changed,
6
+ // instead of discarding and rebuilding the whole real DOM subtree every
7
+ // time (see src/vdom.ks for the diff/patch engine, src/component.ks for
8
+ // where Render()'s return type changed from Element to VElement).
9
+ //
10
+ // Fixed, named fields — not a generic prop bag — because KopScript has no
11
+ // object-literal syntax to build one with. Fixed, named event slots — not
12
+ // an array of handlers — because KopScript has no array-of-function-values
13
+ // type either. Both are real language constraints, not an oversight; see
14
+ // SetAttr below for the escape hatch covering everything not common enough
15
+ // to deserve its own named field.
16
+ class VElement {
17
+ public string Tag;
18
+ // Mutually exclusive with Children and RawHtml — set at most one of the
19
+ // three. TextContent/Children mirrors the same "no mixed text/element
20
+ // content" rule KopScript's own templates already enforce.
21
+ public string TextContent;
22
+ public string ClassName;
23
+ public string Id;
24
+ // The one property patched via direct assignment, never setAttribute —
25
+ // see Element.value's own comment in dom.ks for why (the "default value
26
+ // attribute" vs "current live value property" DOM footgun — the exact
27
+ // property behind the original typing bug this whole effort traces to).
28
+ public string Value;
29
+ public VElement[] Children;
30
+ // An opaque, undiffed leaf — set instead of TextContent/Children for the
31
+ // existing raw-HTML-then-wire-handlers pattern (header.ks/nav.ks). The
32
+ // patch engine treats two VElements with different RawHtml as a single
33
+ // innerHTML assignment, never recursing inside it — the same "opaque
34
+ // blob" treatment `raw string` already gets everywhere else.
35
+ public string RawHtml;
36
+
37
+ // Each defaults to a real no-op, never null — KopScript has no nullable
38
+ // *function* type to fall back on for "no handler set" (see Router.Guard
39
+ // for the same default-real-function pattern already established).
40
+ public (Event) => void OnClick;
41
+ public (Event) => void OnInput;
42
+ public (Event) => void OnBlur;
43
+ public (Event) => void OnChange;
44
+
45
+ // A real HTML attribute not common enough for its own named field (href,
46
+ // src, alt, placeholder, ...) — parallel arrays, since KopScript has no
47
+ // Dictionary type. Never Value (see its own field comment above). Public,
48
+ // read directly by the patch engine (src/vdom.ks) rather than through
49
+ // accessor methods — plain data, same style as this codebase's other
50
+ // plain classes (Note, Dog, ...).
51
+ public string[] ExtraNames;
52
+ public string[] ExtraValues;
53
+
54
+ // Set only once this VElement has been materialized into (or reused as)
55
+ // a real DOM node — null on a freshly-built tree from a not-yet-patched
56
+ // Render() call. The patch engine reads the *previous* render's tree's
57
+ // RealNode to know what to reuse/patch; it never reads the live DOM back
58
+ // to rediscover this (see vdom.ks's own header comment for why).
59
+ public Element? RealNode;
60
+
61
+ constructor(string tag) {
62
+ this.Tag = tag;
63
+ this.TextContent = "";
64
+ this.ClassName = "";
65
+ this.Id = "";
66
+ this.Value = "";
67
+ this.Children = [];
68
+ this.RawHtml = "";
69
+ this.OnClick = (Event e) => {};
70
+ this.OnInput = (Event e) => {};
71
+ this.OnBlur = (Event e) => {};
72
+ this.OnChange = (Event e) => {};
73
+ this.ExtraNames = [];
74
+ this.ExtraValues = [];
75
+ this.RealNode = null;
76
+ }
77
+
78
+ public static VElement Create(string tag) {
79
+ return new VElement(tag);
80
+ }
81
+
82
+ public void AppendChild(VElement child) {
83
+ this.Children = this.Children.Push(child);
84
+ }
85
+
86
+ // Last call for a given name wins if SetAttr is called more than once
87
+ // with the same name on one VElement — the patch engine applies
88
+ // ExtraNames/ExtraValues in order, so a later entry's setAttribute call
89
+ // simply overwrites an earlier one for the same name, no special
90
+ // dedup/replace logic needed here.
91
+ public void SetAttr(string name, string value) {
92
+ this.ExtraNames = this.ExtraNames.Push(name);
93
+ this.ExtraValues = this.ExtraValues.Push(value);
94
+ }
95
+ }