j-templates 8.0.21 → 8.0.23
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/DOM/domNodeConfig.js +3 -0
- package/Node/component.d.ts +7 -1
- package/Node/component.js +8 -0
- package/Node/nodeConfig.d.ts +1 -0
- package/Node/vNode.d.ts +1 -1
- package/Node/vNode.js +59 -12
- package/Node/vNode.types.d.ts +2 -0
- package/package.json +1 -1
package/DOM/domNodeConfig.js
CHANGED
package/Node/component.d.ts
CHANGED
|
@@ -14,6 +14,11 @@ export declare class Component<D = void, T = void, E = {}> {
|
|
|
14
14
|
private scope;
|
|
15
15
|
private templates;
|
|
16
16
|
private componentEvents;
|
|
17
|
+
/**
|
|
18
|
+
* Return if the component's vNode is connected
|
|
19
|
+
* to a parent document
|
|
20
|
+
*/
|
|
21
|
+
get IsConnected(): boolean;
|
|
17
22
|
/**
|
|
18
23
|
* Returns the component's virtual node injector.
|
|
19
24
|
*/
|
|
@@ -51,6 +56,7 @@ export declare class Component<D = void, T = void, E = {}> {
|
|
|
51
56
|
* Override to perform post‑binding initialization.
|
|
52
57
|
*/
|
|
53
58
|
Bound(): void;
|
|
59
|
+
Connected(): void;
|
|
54
60
|
/**
|
|
55
61
|
* Fires a component event.
|
|
56
62
|
*
|
|
@@ -85,6 +91,6 @@ export declare namespace Component {
|
|
|
85
91
|
* @param vnode - The virtual node to be attached.
|
|
86
92
|
* @returns The result of the attachment operation.
|
|
87
93
|
*/
|
|
88
|
-
function Attach(node: any, vnode:
|
|
94
|
+
function Attach(node: any, vnode: vElementNode): vElementNode;
|
|
89
95
|
}
|
|
90
96
|
export {};
|
package/Node/component.js
CHANGED
|
@@ -9,6 +9,13 @@ import { ObservableScope } from "../Store";
|
|
|
9
9
|
* @template E - Event map type for component events.
|
|
10
10
|
*/
|
|
11
11
|
export class Component {
|
|
12
|
+
/**
|
|
13
|
+
* Return if the component's vNode is connected
|
|
14
|
+
* to a parent document
|
|
15
|
+
*/
|
|
16
|
+
get IsConnected() {
|
|
17
|
+
return this.vNode.connected;
|
|
18
|
+
}
|
|
12
19
|
/**
|
|
13
20
|
* Returns the component's virtual node injector.
|
|
14
21
|
*/
|
|
@@ -76,6 +83,7 @@ export class Component {
|
|
|
76
83
|
Bound() {
|
|
77
84
|
Bound.All(this);
|
|
78
85
|
}
|
|
86
|
+
Connected() { }
|
|
79
87
|
/**
|
|
80
88
|
* Fires a component event.
|
|
81
89
|
*
|
package/Node/nodeConfig.d.ts
CHANGED
package/Node/vNode.d.ts
CHANGED
|
@@ -6,5 +6,5 @@ export declare namespace vNode {
|
|
|
6
6
|
function Destroy(vnode: vNodeType): void;
|
|
7
7
|
function DestroyAll(vnodes: vNodeType[]): void;
|
|
8
8
|
function ToFunction<P = HTMLElement, E = HTMLElementEventMap>(type: string | typeof TEXT_NODE | typeof FRAGMENT_NODE, namespace?: string): <T>(config: vNodeConfig<P, E, T>, children?: vNodeType[] | vNodeChildrenFunction<T>) => vElementNode;
|
|
9
|
-
function Attach(node: any, vnode:
|
|
9
|
+
function Attach(node: any, vnode: vElementNode): vElementNode;
|
|
10
10
|
}
|
package/Node/vNode.js
CHANGED
|
@@ -13,6 +13,7 @@ export var vNode;
|
|
|
13
13
|
return {
|
|
14
14
|
definition,
|
|
15
15
|
type: definition.type,
|
|
16
|
+
connected: false,
|
|
16
17
|
injector: definition.componentFactory
|
|
17
18
|
? new Injector()
|
|
18
19
|
: (Injector.Current() ?? new Injector()),
|
|
@@ -71,8 +72,11 @@ export var vNode;
|
|
|
71
72
|
if (vnode.type === FRAGMENT_NODE)
|
|
72
73
|
throw new Error("Cannot attach a fragment directly. A fragment has no DOM node — " +
|
|
73
74
|
"wrap it in a real element (e.g. div) before attaching.");
|
|
75
|
+
// Must create a node + attach before Init so Connected can run correctly
|
|
76
|
+
// on a possible Component instance
|
|
77
|
+
const childNode = vnode.definition.node = CreateNode(vnode);
|
|
78
|
+
NodeConfig.addChild(node, childNode);
|
|
74
79
|
Init(vnode);
|
|
75
|
-
NodeConfig.addChild(node, vnode.node);
|
|
76
80
|
return vnode;
|
|
77
81
|
}
|
|
78
82
|
vNode.Attach = Attach;
|
|
@@ -80,19 +84,22 @@ export var vNode;
|
|
|
80
84
|
function ComponentChildren() {
|
|
81
85
|
return this.Template();
|
|
82
86
|
}
|
|
83
|
-
function
|
|
84
|
-
const { type, namespace, props, attrs, on, data, componentFactory, children, childrenArray, } = vnode.definition;
|
|
85
|
-
let node = null;
|
|
87
|
+
function CreateNode(vnode) {
|
|
86
88
|
switch (vnode.type) {
|
|
87
89
|
case FRAGMENT_NODE:
|
|
88
|
-
|
|
90
|
+
return null;
|
|
89
91
|
case TEXT_NODE:
|
|
90
|
-
|
|
91
|
-
break;
|
|
92
|
+
return vnode.definition.node ?? NodeConfig.createTextNode();
|
|
92
93
|
default:
|
|
93
|
-
|
|
94
|
-
break;
|
|
94
|
+
return vnode.definition.node ?? NodeConfig.createNode(vnode.definition.type, vnode.definition.namespace);
|
|
95
95
|
}
|
|
96
|
+
}
|
|
97
|
+
function InitNode(vnode, parentNode) {
|
|
98
|
+
const {
|
|
99
|
+
/* type,
|
|
100
|
+
namespace, */
|
|
101
|
+
props, attrs, on, data, componentFactory, children, childrenArray, } = vnode.definition;
|
|
102
|
+
const node = vnode.node = CreateNode(vnode);
|
|
96
103
|
vnode.definition = null;
|
|
97
104
|
vnode.parentNode = parentNode;
|
|
98
105
|
if (props) {
|
|
@@ -130,7 +137,7 @@ function InitNode(vnode, parentNode) {
|
|
|
130
137
|
}
|
|
131
138
|
if (componentFactory) {
|
|
132
139
|
vnode.component = Injector.Scope(vnode.injector, componentFactory, vnode);
|
|
133
|
-
vnode.component.Bound();
|
|
140
|
+
// vnode.component.Bound();
|
|
134
141
|
Children(vnode, ComponentChildren.bind(vnode.component));
|
|
135
142
|
}
|
|
136
143
|
else if (childrenArray) {
|
|
@@ -173,7 +180,7 @@ function CreateChildrenScope(vnode, children, data) {
|
|
|
173
180
|
return ObservableScope.Create(DynamicChildrenFunction.bind(null, vnode.injector, children, data));
|
|
174
181
|
}
|
|
175
182
|
function ToVNodeType(children) {
|
|
176
|
-
return typeof children === "string" ? { type: STRING_NODE, node: children } : children;
|
|
183
|
+
return typeof children === "string" ? { type: STRING_NODE, connected: false, node: children } : children;
|
|
177
184
|
}
|
|
178
185
|
function GetNextNodes(injector, children, data) {
|
|
179
186
|
return ToVNodeType(Injector.Scope(injector, children, data));
|
|
@@ -236,14 +243,18 @@ function UpdateChildren(vnode, init = false, skipInit = false) {
|
|
|
236
243
|
if (vnode.destroyed || children !== vnode.children)
|
|
237
244
|
return;
|
|
238
245
|
if (init) {
|
|
239
|
-
if (vnode.node !== null)
|
|
246
|
+
if (vnode.node !== null) {
|
|
240
247
|
NodeConfig.reconcileChildren(vnode.node, CleanupChildrenArray(vnode.children));
|
|
248
|
+
vnode.component?.Bound();
|
|
249
|
+
FireConnected(vnode, true);
|
|
250
|
+
}
|
|
241
251
|
}
|
|
242
252
|
else if (!async) {
|
|
243
253
|
let reconcileNode = vnode;
|
|
244
254
|
while (reconcileNode.node === null)
|
|
245
255
|
reconcileNode = reconcileNode.parentNode;
|
|
246
256
|
NodeConfig.reconcileChildren(reconcileNode.node, CleanupChildrenArray(reconcileNode.children));
|
|
257
|
+
FireConnected(vnode, true);
|
|
247
258
|
}
|
|
248
259
|
else {
|
|
249
260
|
NodeConfig.scheduleUpdate(function () {
|
|
@@ -253,11 +264,47 @@ function UpdateChildren(vnode, init = false, skipInit = false) {
|
|
|
253
264
|
while (reconcileNode.node === null)
|
|
254
265
|
reconcileNode = reconcileNode.parentNode;
|
|
255
266
|
NodeConfig.reconcileChildren(reconcileNode.node, CleanupChildrenArray(reconcileNode.children));
|
|
267
|
+
FireConnected(vnode, true);
|
|
256
268
|
});
|
|
257
269
|
}
|
|
258
270
|
});
|
|
259
271
|
});
|
|
260
272
|
}
|
|
273
|
+
function FireConnected(vnode, root = false) {
|
|
274
|
+
if ((!root && vnode.connected) ||
|
|
275
|
+
(vnode.type !== FRAGMENT_NODE && vnode.node === null))
|
|
276
|
+
return;
|
|
277
|
+
switch (vnode.type) {
|
|
278
|
+
case FRAGMENT_NODE:
|
|
279
|
+
break;
|
|
280
|
+
default: {
|
|
281
|
+
if (!vnode.connected) {
|
|
282
|
+
vnode.connected = NodeConfig.isConnected(vnode.node);
|
|
283
|
+
switch (vnode.type) {
|
|
284
|
+
case STRING_NODE:
|
|
285
|
+
case TEXT_NODE:
|
|
286
|
+
break;
|
|
287
|
+
default:
|
|
288
|
+
vnode.connected && vnode.component?.Connected();
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
break;
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
if (vnode.type !== FRAGMENT_NODE && !vnode.connected)
|
|
295
|
+
return;
|
|
296
|
+
switch (vnode.type) {
|
|
297
|
+
case STRING_NODE:
|
|
298
|
+
case TEXT_NODE:
|
|
299
|
+
break;
|
|
300
|
+
default: {
|
|
301
|
+
const children = vnode.children;
|
|
302
|
+
const count = children?.length;
|
|
303
|
+
for (let x = 0; x < count; x++)
|
|
304
|
+
FireConnected(children[x]);
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
}
|
|
261
308
|
function ScheduledAssignment(assign) {
|
|
262
309
|
let scheduled = false;
|
|
263
310
|
return function (scope) {
|
package/Node/vNode.types.d.ts
CHANGED
|
@@ -27,10 +27,12 @@ export type vNodeConfig<P = HTMLElement, E = HTMLElementEventMap, T = never> = {
|
|
|
27
27
|
};
|
|
28
28
|
export type vStringNode = {
|
|
29
29
|
type: typeof STRING_NODE;
|
|
30
|
+
connected: boolean;
|
|
30
31
|
node: string;
|
|
31
32
|
};
|
|
32
33
|
export type vElementNode = {
|
|
33
34
|
type: string | typeof TEXT_NODE | typeof FRAGMENT_NODE;
|
|
35
|
+
connected: boolean;
|
|
34
36
|
definition: vNodeDefinition<any, any, any>;
|
|
35
37
|
injector: Injector;
|
|
36
38
|
parentNode: vElementNode | null;
|