@estjs/template 0.0.13-beta.6 → 0.0.13
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/dist/template.cjs.js +14 -14
- package/dist/template.cjs.js.map +1 -1
- package/dist/template.d.cts +27 -30
- package/dist/template.d.ts +27 -30
- package/dist/template.dev.cjs.js +387 -314
- package/dist/template.dev.esm.js +389 -316
- package/dist/template.esm.js +3 -3
- package/dist/template.esm.js.map +1 -1
- package/package.json +3 -3
package/dist/template.dev.esm.js
CHANGED
|
@@ -1,51 +1,66 @@
|
|
|
1
|
-
import { isString, isFunction,
|
|
1
|
+
import { isString, isFunction, isArray, isSymbol, escape, startsWith, isPrimitive, isNil, capitalizeFirstLetter, coerceArray, isFalsy, kebabCase } from '@estjs/shared';
|
|
2
2
|
import { shallowSignal, isSignal, useReactive, useEffect, useSignal } from '@estjs/signal';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
|
-
* @estjs/template v0.0.13
|
|
5
|
+
* @estjs/template v0.0.13
|
|
6
6
|
* (c) 2023-Present jiangxd <jiangxd2016@gmail.com>
|
|
7
7
|
* @license MIT
|
|
8
8
|
**/
|
|
9
9
|
|
|
10
10
|
|
|
11
11
|
// src/shared-config.ts
|
|
12
|
-
var
|
|
12
|
+
var EVENT_PREFIX = "on";
|
|
13
|
+
var UPDATE_PREFIX = "update";
|
|
14
|
+
var CHILDREN_PROP = "children";
|
|
15
|
+
var EMPTY_TEMPLATE = "";
|
|
16
|
+
var FRAGMENT_PROP_KEY = "0";
|
|
17
|
+
var SINGLE_PROP_KEY = "1";
|
|
18
|
+
var PLACEHOLDER = " __PLACEHOLDER__ ";
|
|
13
19
|
var RenderContext = class {
|
|
14
20
|
constructor() {
|
|
15
21
|
this.renderMode = 0 /* CLIENT */;
|
|
16
22
|
}
|
|
23
|
+
// Getter to check if the current mode is SSG
|
|
17
24
|
get isSSG() {
|
|
18
25
|
return this.renderMode === 1 /* SSG */;
|
|
19
26
|
}
|
|
27
|
+
// Getter to check if the current mode is SSR
|
|
20
28
|
get isSSR() {
|
|
21
29
|
return this.renderMode === 2 /* SSR */;
|
|
22
30
|
}
|
|
31
|
+
// Getter to check if the current mode is Client
|
|
23
32
|
get isClient() {
|
|
24
33
|
return this.renderMode === 0 /* CLIENT */;
|
|
25
34
|
}
|
|
35
|
+
// Set render mode to SSR
|
|
26
36
|
setSSR() {
|
|
27
37
|
this.renderMode = 2 /* SSR */;
|
|
28
38
|
}
|
|
39
|
+
// Set render mode to SSG
|
|
29
40
|
setSSG() {
|
|
30
41
|
this.renderMode = 1 /* SSG */;
|
|
31
42
|
}
|
|
43
|
+
// Set render mode to Client
|
|
32
44
|
setClient() {
|
|
33
45
|
this.renderMode = 0 /* CLIENT */;
|
|
34
46
|
}
|
|
35
47
|
};
|
|
36
48
|
var renderContext = new RenderContext();
|
|
49
|
+
var componentMap = /* @__PURE__ */ new Map();
|
|
37
50
|
function enterComponent(temp, index) {
|
|
38
51
|
componentMap.set(temp, {
|
|
39
52
|
index
|
|
40
53
|
});
|
|
41
54
|
}
|
|
42
55
|
function getComponentIndex(temp) {
|
|
43
|
-
|
|
56
|
+
var _a;
|
|
57
|
+
return (_a = componentMap.get(temp)) == null ? void 0 : _a.index;
|
|
44
58
|
}
|
|
45
59
|
|
|
46
60
|
// src/lifecycle-context.ts
|
|
47
61
|
var _LifecycleContext = class _LifecycleContext {
|
|
48
62
|
constructor() {
|
|
63
|
+
// Hooks for different lifecycle stages
|
|
49
64
|
this.hooks = {
|
|
50
65
|
mounted: /* @__PURE__ */ new Set(),
|
|
51
66
|
destroy: /* @__PURE__ */ new Set()
|
|
@@ -55,28 +70,35 @@ var _LifecycleContext = class _LifecycleContext {
|
|
|
55
70
|
}
|
|
56
71
|
removeEventListener() {
|
|
57
72
|
}
|
|
73
|
+
// Add a hook for a specific lifecycle stage
|
|
58
74
|
addHook(hook, cb) {
|
|
59
75
|
var _a;
|
|
60
76
|
(_a = this.hooks[hook]) == null ? void 0 : _a.add(cb);
|
|
61
77
|
}
|
|
78
|
+
// Get a value from the static context
|
|
62
79
|
getContext(context) {
|
|
63
80
|
return _LifecycleContext.context[context];
|
|
64
81
|
}
|
|
82
|
+
// Set a value in the static context
|
|
65
83
|
setContext(context, value) {
|
|
66
84
|
_LifecycleContext.context[context] = value;
|
|
67
85
|
}
|
|
86
|
+
// Initialize the static reference
|
|
68
87
|
initRef() {
|
|
69
88
|
_LifecycleContext.ref = this;
|
|
70
89
|
}
|
|
90
|
+
// Remove the static reference
|
|
71
91
|
removeRef() {
|
|
72
92
|
_LifecycleContext.ref = null;
|
|
73
93
|
}
|
|
94
|
+
// Clear all hooks
|
|
74
95
|
clearHooks() {
|
|
75
96
|
Object.values(this.hooks).forEach((set) => set.clear());
|
|
76
97
|
}
|
|
77
98
|
};
|
|
78
|
-
// current context
|
|
99
|
+
// Static reference to the current context
|
|
79
100
|
_LifecycleContext.ref = null;
|
|
101
|
+
// Static context to store shared values
|
|
80
102
|
_LifecycleContext.context = {};
|
|
81
103
|
var LifecycleContext = _LifecycleContext;
|
|
82
104
|
|
|
@@ -92,29 +114,39 @@ var SSGNode = class extends LifecycleContext {
|
|
|
92
114
|
this.props = props;
|
|
93
115
|
this.key = key;
|
|
94
116
|
enterComponent(template, componentIndex);
|
|
117
|
+
this.templates = this.processTemplate();
|
|
118
|
+
}
|
|
119
|
+
// Process the template and return an array of processed strings
|
|
120
|
+
processTemplate() {
|
|
95
121
|
if (isArray(this.template)) {
|
|
96
|
-
const PLACEHOLDER = " __PLACEHOLDER__ ";
|
|
97
122
|
const htmlString = this.template.join(PLACEHOLDER);
|
|
98
|
-
const processedString =
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
return match;
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
123
|
+
const processedString = this.processHtmlString(htmlString);
|
|
124
|
+
return processedString.split(PLACEHOLDER);
|
|
125
|
+
}
|
|
126
|
+
return [];
|
|
127
|
+
}
|
|
128
|
+
// Process HTML string by adding component index and handling text nodes
|
|
129
|
+
processHtmlString(htmlString) {
|
|
130
|
+
return htmlString.replaceAll(/(<[^>]+>)|([^<]+)/g, (match, p1, p2) => {
|
|
131
|
+
if (p1) {
|
|
132
|
+
if (p1.includes("data-ci")) return match;
|
|
133
|
+
return p1.replace(/<\s*([\da-z]+)(\s[^>]*)?>/i, (_, tagName, attrs) => {
|
|
134
|
+
return `<${tagName} data-ci="${componentIndex}"${attrs || ""}>`;
|
|
135
|
+
});
|
|
136
|
+
} else if (p2 && p2.replace(PLACEHOLDER, "").trim()) {
|
|
137
|
+
return `<!--${0 /* TEXT */}-${componentIndex}-->${p2}<!$>`;
|
|
138
|
+
}
|
|
139
|
+
return match;
|
|
140
|
+
});
|
|
111
141
|
}
|
|
142
|
+
// Mount the SSGNode and return the rendered string
|
|
112
143
|
mount() {
|
|
113
144
|
this.initRef();
|
|
114
145
|
const output = this.render();
|
|
115
146
|
this.removeRef();
|
|
116
147
|
return output;
|
|
117
148
|
}
|
|
149
|
+
// Render the SSGNode
|
|
118
150
|
render() {
|
|
119
151
|
if (isFunction(this.template)) {
|
|
120
152
|
const root = this.template(this.props);
|
|
@@ -124,57 +156,66 @@ var SSGNode = class extends LifecycleContext {
|
|
|
124
156
|
return String(root);
|
|
125
157
|
}
|
|
126
158
|
}
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
const
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
this.template[findIndex] += children;
|
|
138
|
-
});
|
|
159
|
+
return this.renderTemplate();
|
|
160
|
+
}
|
|
161
|
+
// Render the template by processing props and children
|
|
162
|
+
renderTemplate() {
|
|
163
|
+
Object.entries(this.props).forEach(([key, cur]) => {
|
|
164
|
+
const children = cur.children;
|
|
165
|
+
this.normalizeProps(cur);
|
|
166
|
+
const findIndex = this.templates.findIndex((t) => t.includes(`data-hk="${key}"`));
|
|
167
|
+
if (children) {
|
|
168
|
+
this.renderChildren(children, findIndex);
|
|
139
169
|
}
|
|
140
|
-
this.
|
|
170
|
+
this.templates[findIndex] = this.templates[findIndex].replace(
|
|
141
171
|
`data-hk="${key}"`,
|
|
142
|
-
`data-hk="${key}" ${generateAttributes(cur)}`
|
|
172
|
+
`data-hk="${key}" ${this.generateAttributes(cur)}`
|
|
143
173
|
);
|
|
144
174
|
});
|
|
145
|
-
return
|
|
175
|
+
return this.templates.join("");
|
|
146
176
|
}
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
177
|
+
// Normalize props by removing children and handling signals
|
|
178
|
+
normalizeProps(props) {
|
|
179
|
+
Object.entries(props).forEach(([key, value]) => {
|
|
180
|
+
if (key === "children") {
|
|
181
|
+
delete props[key];
|
|
182
|
+
} else if (isFunction(value)) {
|
|
183
|
+
delete props[key];
|
|
184
|
+
} else if (isSignal(value)) {
|
|
185
|
+
props[key] = value.value;
|
|
186
|
+
}
|
|
187
|
+
});
|
|
188
|
+
}
|
|
189
|
+
// Generate HTML attributes string from props
|
|
190
|
+
generateAttributes(props) {
|
|
191
|
+
return Object.entries(props).filter(([key, value]) => key !== "children" && !isFunction(value)).map(([key, value]) => `${key}="${escape(String(value))}"`).join(" ");
|
|
192
|
+
}
|
|
193
|
+
// Render children and append them to the template
|
|
194
|
+
renderChildren(children, findIndex) {
|
|
195
|
+
children.forEach(([child]) => {
|
|
196
|
+
componentIndex++;
|
|
197
|
+
const renderedChild = this.renderChild(child);
|
|
198
|
+
this.templates[findIndex] += renderedChild;
|
|
199
|
+
});
|
|
200
|
+
}
|
|
201
|
+
// Render a single child node
|
|
202
|
+
renderChild(child) {
|
|
203
|
+
if (isFunction(child)) {
|
|
204
|
+
return this.renderChild(child(this.props));
|
|
205
|
+
} else if (isSignal(child)) {
|
|
206
|
+
return `<!--${1 /* TEXT_COMPONENT */}-${componentIndex}-->${child.value}<!$>`;
|
|
207
|
+
} else if (isSSGNode(child)) {
|
|
208
|
+
const childResult = child.mount();
|
|
209
|
+
return isFunction(childResult) ? childResult(this.props) : extractSignal(childResult);
|
|
210
|
+
} else {
|
|
211
|
+
return `<!--${1 /* TEXT_COMPONENT */}-${componentIndex}-->${child}<!$>`;
|
|
156
212
|
}
|
|
157
|
-
});
|
|
158
|
-
}
|
|
159
|
-
function generateAttributes(props) {
|
|
160
|
-
return Object.entries(props).filter(([key, value]) => key !== "children" && !isFunction(value)).map(([key, value]) => `${key}="${escape(String(value))}"`).join(" ");
|
|
161
|
-
}
|
|
162
|
-
function renderChildren(children, prop) {
|
|
163
|
-
if (isFunction(children)) {
|
|
164
|
-
return renderChildren(children(prop), prop);
|
|
165
|
-
} else if (isSignal(children)) {
|
|
166
|
-
return `<!--${1 /* TEXT_COMPONENT */}-${componentIndex}-->${children.value}<!$>`;
|
|
167
|
-
} else if (isSSGNode(children)) {
|
|
168
|
-
const childResult = children.mount();
|
|
169
|
-
return isFunction(childResult) ? childResult(prop) : extractSignal(childResult);
|
|
170
|
-
} else {
|
|
171
|
-
return `<!--${1 /* TEXT_COMPONENT */}-${componentIndex}-->${children}<!$>`;
|
|
172
213
|
}
|
|
173
|
-
}
|
|
214
|
+
};
|
|
174
215
|
|
|
175
216
|
// src/utils.ts
|
|
176
|
-
var
|
|
177
|
-
var
|
|
217
|
+
var SELF_CLOSING_TAGS = "area,base,br,col,embed,hr,img,input,link,meta,param,source,track,wbr".split(",");
|
|
218
|
+
var HTML_TAGS = "a,abbr,acronym,address,applet,area,article,aside,audio,b,base,basefont,bdi,bdo,bgsound,big,blink,blockquote,body,br,button,canvas,caption,center,cite,code,col,colgroup,command,content,data,datalist,dd,del,details,dfn,dialog,dir,div,dl,dt,em,embed,fieldset,figcaption,figure,font,footer,form,frame,frameset,h1,h2,h3,h4,h5,h6,head,header,hgroup,hr,html,i,iframe,image,img,input,ins,kbd,keygen,label,legend,li,link,listing,main,map,mark,marquee,menu,menuitem,meta,meter,nav,nobr,noframes,noscript,object,ol,optgroup,option,output,p,param,picture,plaintext,pre,progress,q,rb,rp,rt,rtc,ruby,s,samp,script,section,select,shadow,small,source,spacer,span,strike,strong,style,sub,summary,sup,table,tbody,td,template,textarea,tfoot,th,thead,time,title,tr,track,tt,u,ul,var,video,wbr,xmp".split(
|
|
178
219
|
","
|
|
179
220
|
);
|
|
180
221
|
function coerceNode(data) {
|
|
@@ -211,26 +252,33 @@ function replaceChild(parent, node, child) {
|
|
|
211
252
|
}
|
|
212
253
|
function setAttribute(element, attr, value) {
|
|
213
254
|
if (attr === "class") {
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
255
|
+
setClassAttribute(element, value);
|
|
256
|
+
} else if (attr === "style") {
|
|
257
|
+
setStyleAttribute(element, value);
|
|
258
|
+
} else {
|
|
259
|
+
setGenericAttribute(element, attr, value);
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
function setClassAttribute(element, value) {
|
|
263
|
+
if (typeof value === "string") {
|
|
264
|
+
element.className = value;
|
|
265
|
+
} else if (isArray(value)) {
|
|
266
|
+
element.className = value.join(" ");
|
|
267
|
+
} else if (value && typeof value === "object") {
|
|
268
|
+
element.className = Object.entries(value).reduce((acc, [key, value2]) => acc + (value2 ? ` ${key}` : ""), "").trim();
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
function setStyleAttribute(element, value) {
|
|
272
|
+
if (typeof value === "string") {
|
|
273
|
+
element.style.cssText = value;
|
|
274
|
+
} else if (value && typeof value === "object") {
|
|
275
|
+
const obj = value;
|
|
276
|
+
Object.entries(obj).forEach(([key, value2]) => {
|
|
277
|
+
element.style.setProperty(kebabCase(key), String(value2));
|
|
278
|
+
});
|
|
233
279
|
}
|
|
280
|
+
}
|
|
281
|
+
function setGenericAttribute(element, attr, value) {
|
|
234
282
|
if (isFalsy(value)) {
|
|
235
283
|
element.removeAttribute(attr);
|
|
236
284
|
} else if (value === true) {
|
|
@@ -313,7 +361,7 @@ function closeHtmlTags(input) {
|
|
|
313
361
|
if (tagStack.length > 0) {
|
|
314
362
|
tagStack.pop();
|
|
315
363
|
}
|
|
316
|
-
} else if (!
|
|
364
|
+
} else if (!SELF_CLOSING_TAGS.includes(tagName)) {
|
|
317
365
|
tagStack.push(tagName);
|
|
318
366
|
}
|
|
319
367
|
output.push(fullMatch);
|
|
@@ -328,14 +376,10 @@ function closeHtmlTags(input) {
|
|
|
328
376
|
return output.join("");
|
|
329
377
|
}
|
|
330
378
|
function isHtmlTagName(tagName) {
|
|
331
|
-
return
|
|
379
|
+
return HTML_TAGS.includes(tagName);
|
|
332
380
|
}
|
|
333
381
|
function convertToHtmlTag(tagName) {
|
|
334
|
-
|
|
335
|
-
return `<${tagName}/>`;
|
|
336
|
-
} else {
|
|
337
|
-
return `<${tagName}></${tagName}>`;
|
|
338
|
-
}
|
|
382
|
+
return SELF_CLOSING_TAGS.includes(tagName) ? `<${tagName}/>` : `<${tagName}></${tagName}>`;
|
|
339
383
|
}
|
|
340
384
|
function extractSignal(signal) {
|
|
341
385
|
if (isSignal(signal)) {
|
|
@@ -353,19 +397,28 @@ var ComponentNode = class extends LifecycleContext {
|
|
|
353
397
|
this.emitter = /* @__PURE__ */ new Set();
|
|
354
398
|
this.rootNode = null;
|
|
355
399
|
this.trackMap = /* @__PURE__ */ new Map();
|
|
356
|
-
this.
|
|
400
|
+
this.key || (this.key = props == null ? void 0 : props.key);
|
|
401
|
+
this.proxyProps = this.createProxyProps(props);
|
|
402
|
+
}
|
|
403
|
+
// Create reactive props
|
|
404
|
+
createProxyProps(props) {
|
|
405
|
+
if (!props) return {};
|
|
406
|
+
return useReactive(
|
|
357
407
|
props,
|
|
358
|
-
(
|
|
359
|
-
)
|
|
408
|
+
(key) => startsWith(key, EVENT_PREFIX) || startsWith(key, UPDATE_PREFIX) || key === CHILDREN_PROP
|
|
409
|
+
);
|
|
360
410
|
}
|
|
411
|
+
// Getter for the first child node
|
|
361
412
|
get firstChild() {
|
|
362
413
|
var _a, _b;
|
|
363
414
|
return (_b = (_a = this.rootNode) == null ? void 0 : _a.firstChild) != null ? _b : null;
|
|
364
415
|
}
|
|
416
|
+
// Getter to check if the node is connected to the DOM
|
|
365
417
|
get isConnected() {
|
|
366
418
|
var _a, _b;
|
|
367
419
|
return (_b = (_a = this.rootNode) == null ? void 0 : _a.isConnected) != null ? _b : false;
|
|
368
420
|
}
|
|
421
|
+
// Method to mount the component to the DOM
|
|
369
422
|
mount(parent, before) {
|
|
370
423
|
var _a, _b, _c, _d;
|
|
371
424
|
if (!isFunction(this.template)) {
|
|
@@ -377,32 +430,37 @@ var ComponentNode = class extends LifecycleContext {
|
|
|
377
430
|
this.initRef();
|
|
378
431
|
this.rootNode = this.template(this.proxyProps);
|
|
379
432
|
const mountedNode = (_d = (_c = this.rootNode) == null ? void 0 : _c.mount(parent, before)) != null ? _d : [];
|
|
380
|
-
this.
|
|
433
|
+
this.callMountHooks();
|
|
381
434
|
this.patchProps(this.props);
|
|
382
435
|
this.removeRef();
|
|
383
436
|
return mountedNode;
|
|
384
437
|
}
|
|
438
|
+
// Method to unmount the component from the DOM
|
|
385
439
|
unmount() {
|
|
386
440
|
var _a;
|
|
387
|
-
this.
|
|
441
|
+
this.callDestroyHooks();
|
|
388
442
|
this.clearHooks();
|
|
389
443
|
(_a = this.rootNode) == null ? void 0 : _a.unmount();
|
|
390
444
|
this.rootNode = null;
|
|
391
445
|
this.proxyProps = {};
|
|
446
|
+
this.clearEmitter();
|
|
447
|
+
}
|
|
448
|
+
// Private method to call mount hooks
|
|
449
|
+
callMountHooks() {
|
|
450
|
+
this.hooks.mounted.forEach((handler) => handler());
|
|
451
|
+
}
|
|
452
|
+
// Private method to call destroy hooks
|
|
453
|
+
callDestroyHooks() {
|
|
454
|
+
this.hooks.destroy.forEach((handler) => handler());
|
|
455
|
+
}
|
|
456
|
+
// Private method to clear the event emitter
|
|
457
|
+
clearEmitter() {
|
|
392
458
|
for (const cleanup of this.emitter) {
|
|
393
459
|
cleanup();
|
|
394
460
|
}
|
|
395
461
|
this.emitter.clear();
|
|
396
462
|
}
|
|
397
|
-
|
|
398
|
-
* Inherit props and state from another ComponentNode.
|
|
399
|
-
* It will:
|
|
400
|
-
* 1. Copy props from the node to this proxyProps.
|
|
401
|
-
* 2. Copy the rootNode, trackMap and hooks from the node.
|
|
402
|
-
* 3. Copy the props from the node to this.
|
|
403
|
-
* 4. Patch props from the props passed in the constructor.
|
|
404
|
-
* @param node The node to inherit from.
|
|
405
|
-
*/
|
|
463
|
+
// Method to inherit properties from another ComponentNode
|
|
406
464
|
inheritNode(node) {
|
|
407
465
|
Object.assign(this.proxyProps, node.proxyProps);
|
|
408
466
|
this.rootNode = node.rootNode;
|
|
@@ -412,12 +470,7 @@ var ComponentNode = class extends LifecycleContext {
|
|
|
412
470
|
this.props = node.props;
|
|
413
471
|
this.patchProps(props);
|
|
414
472
|
}
|
|
415
|
-
|
|
416
|
-
* Get a NodeTrack from the trackMap. If the track is not in the trackMap, create a new one.
|
|
417
|
-
* Then, call the cleanup function to remove any previously registered hooks.
|
|
418
|
-
* @param trackKey the key of the node track to get.
|
|
419
|
-
* @returns the NodeTrack, cleaned up and ready to use.
|
|
420
|
-
*/
|
|
473
|
+
// Private method to get or create a NodeTrack
|
|
421
474
|
getNodeTrack(trackKey) {
|
|
422
475
|
let track = this.trackMap.get(trackKey);
|
|
423
476
|
if (!track) {
|
|
@@ -428,39 +481,47 @@ var ComponentNode = class extends LifecycleContext {
|
|
|
428
481
|
track.cleanup();
|
|
429
482
|
return track;
|
|
430
483
|
}
|
|
431
|
-
|
|
432
|
-
* Patch the props of this node.
|
|
433
|
-
* It will:
|
|
434
|
-
* 1. Iterate the props and patch it.
|
|
435
|
-
* 2. If the prop is a event handler, add a event listener to the first child of the node.
|
|
436
|
-
* 3. If the prop is a ref, set the first child of the node to the ref.
|
|
437
|
-
* 4. If the prop is a update handler, update the prop in the node's props.
|
|
438
|
-
* 5. If the prop is a normal prop, create a signal for it and then patch it.
|
|
439
|
-
* @param props The props to patch.
|
|
440
|
-
*/
|
|
484
|
+
// Method to patch props onto the component
|
|
441
485
|
patchProps(props) {
|
|
442
|
-
var _a
|
|
486
|
+
var _a;
|
|
443
487
|
if (!props) {
|
|
444
488
|
return;
|
|
445
489
|
}
|
|
446
490
|
for (const [key, prop] of Object.entries(props)) {
|
|
447
|
-
if (startsWith(key,
|
|
448
|
-
|
|
449
|
-
const cleanup = addEventListener(this.rootNode.nodes[0], event, prop);
|
|
450
|
-
this.emitter.add(cleanup);
|
|
491
|
+
if (startsWith(key, EVENT_PREFIX) && ((_a = this.rootNode) == null ? void 0 : _a.firstChild)) {
|
|
492
|
+
this.patchEventListener(key, prop);
|
|
451
493
|
} else if (key === "ref") {
|
|
452
|
-
|
|
453
|
-
} else if (startsWith(key,
|
|
454
|
-
this.
|
|
455
|
-
} else if (key !==
|
|
456
|
-
|
|
457
|
-
track.cleanup = useEffect(() => {
|
|
458
|
-
this.proxyProps[key] = isFunction(prop) ? prop() : prop;
|
|
459
|
-
});
|
|
494
|
+
this.patchRef(prop);
|
|
495
|
+
} else if (startsWith(key, UPDATE_PREFIX)) {
|
|
496
|
+
this.patchUpdateHandler(key, prop);
|
|
497
|
+
} else if (key !== CHILDREN_PROP) {
|
|
498
|
+
this.patchNormalProp(key, prop);
|
|
460
499
|
}
|
|
461
500
|
}
|
|
462
501
|
this.props = props;
|
|
463
502
|
}
|
|
503
|
+
// Private method to patch event listeners
|
|
504
|
+
patchEventListener(key, prop) {
|
|
505
|
+
const event = key.slice(2).toLowerCase();
|
|
506
|
+
const cleanup = addEventListener(this.rootNode.nodes[0], event, prop);
|
|
507
|
+
this.emitter.add(cleanup);
|
|
508
|
+
}
|
|
509
|
+
// Private method to patch ref
|
|
510
|
+
patchRef(prop) {
|
|
511
|
+
var _a, _b;
|
|
512
|
+
prop.value = (_b = (_a = this.rootNode) == null ? void 0 : _a.firstChild) != null ? _b : null;
|
|
513
|
+
}
|
|
514
|
+
// Private method to patch update handlers
|
|
515
|
+
patchUpdateHandler(key, prop) {
|
|
516
|
+
this.props[key] = extractSignal(prop);
|
|
517
|
+
}
|
|
518
|
+
// Private method to patch normal props
|
|
519
|
+
patchNormalProp(key, prop) {
|
|
520
|
+
const track = this.getNodeTrack(key);
|
|
521
|
+
track.cleanup = useEffect(() => {
|
|
522
|
+
this.proxyProps[key] = isFunction(prop) ? prop() : prop;
|
|
523
|
+
});
|
|
524
|
+
}
|
|
464
525
|
};
|
|
465
526
|
|
|
466
527
|
// src/patch.ts
|
|
@@ -576,6 +637,7 @@ var TemplateNode = class {
|
|
|
576
637
|
this.template = template;
|
|
577
638
|
this.props = props;
|
|
578
639
|
this.key = key;
|
|
640
|
+
// Private properties for managing the node's state
|
|
579
641
|
this.treeMap = /* @__PURE__ */ new Map();
|
|
580
642
|
this.mounted = false;
|
|
581
643
|
this.nodes = [];
|
|
@@ -587,18 +649,21 @@ var TemplateNode = class {
|
|
|
587
649
|
this.componentIndex = getComponentIndex(this.template);
|
|
588
650
|
}
|
|
589
651
|
}
|
|
590
|
-
|
|
591
|
-
}
|
|
592
|
-
removeEventListener() {
|
|
593
|
-
}
|
|
652
|
+
// Getter for the first child node
|
|
594
653
|
get firstChild() {
|
|
595
654
|
var _a;
|
|
596
655
|
return (_a = this.nodes[0]) != null ? _a : null;
|
|
597
656
|
}
|
|
598
|
-
// is
|
|
657
|
+
// Getter to check if the node is connected to the DOM
|
|
599
658
|
get isConnected() {
|
|
600
659
|
return this.mounted;
|
|
601
660
|
}
|
|
661
|
+
// Placeholder methods for event handling
|
|
662
|
+
addEventListener() {
|
|
663
|
+
}
|
|
664
|
+
removeEventListener() {
|
|
665
|
+
}
|
|
666
|
+
// Method to mount the node to the DOM
|
|
602
667
|
mount(parent, before) {
|
|
603
668
|
var _a;
|
|
604
669
|
this.parent = parent;
|
|
@@ -628,43 +693,45 @@ var TemplateNode = class {
|
|
|
628
693
|
this.mounted = true;
|
|
629
694
|
return this.nodes;
|
|
630
695
|
}
|
|
696
|
+
// Method to unmount the node from the DOM
|
|
631
697
|
unmount() {
|
|
698
|
+
var _a, _b;
|
|
632
699
|
this.trackMap.forEach((track) => {
|
|
633
|
-
var
|
|
634
|
-
(
|
|
700
|
+
var _a2;
|
|
701
|
+
(_a2 = track.cleanup) == null ? void 0 : _a2.call(track);
|
|
635
702
|
});
|
|
636
703
|
this.trackMap.clear();
|
|
637
704
|
this.treeMap.clear();
|
|
638
705
|
this.nodes.forEach((node) => removeChild(node));
|
|
639
706
|
if (!this.template.innerHTML && !this.nodes.length) {
|
|
640
|
-
this.props
|
|
641
|
-
|
|
642
|
-
if (
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
if (node.nodeType === Node.TEXT_NODE && node.textContent === `${i}`) {
|
|
646
|
-
(_a2 = this.parent) == null ? void 0 : _a2.removeChild(node);
|
|
647
|
-
}
|
|
707
|
+
const children = (_b = (_a = this.props) == null ? void 0 : _a[FRAGMENT_PROP_KEY]) == null ? void 0 : _b.children;
|
|
708
|
+
if (children) {
|
|
709
|
+
if (isArray(children)) {
|
|
710
|
+
children.forEach((child) => {
|
|
711
|
+
this.deleteFragmentTextNode(child);
|
|
648
712
|
});
|
|
649
713
|
} else {
|
|
650
|
-
|
|
714
|
+
this.deleteFragmentTextNode(children);
|
|
651
715
|
}
|
|
652
|
-
}
|
|
716
|
+
}
|
|
653
717
|
}
|
|
654
718
|
this.nodes = [];
|
|
655
719
|
this.mounted = false;
|
|
656
720
|
}
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
721
|
+
deleteFragmentTextNode(child) {
|
|
722
|
+
var _a;
|
|
723
|
+
if (isPrimitive(child)) {
|
|
724
|
+
(_a = this.parent) == null ? void 0 : _a.childNodes.forEach((node) => {
|
|
725
|
+
var _a2;
|
|
726
|
+
if (node.nodeType === Node.TEXT_NODE && node.textContent === `${child}`) {
|
|
727
|
+
(_a2 = this.parent) == null ? void 0 : _a2.removeChild(node);
|
|
728
|
+
}
|
|
729
|
+
});
|
|
730
|
+
} else {
|
|
731
|
+
removeChild(child);
|
|
732
|
+
}
|
|
667
733
|
}
|
|
734
|
+
// Method to inherit properties from another TemplateNode
|
|
668
735
|
inheritNode(node) {
|
|
669
736
|
this.mounted = node.mounted;
|
|
670
737
|
this.nodes = node.nodes;
|
|
@@ -674,55 +741,129 @@ var TemplateNode = class {
|
|
|
674
741
|
this.props = node.props;
|
|
675
742
|
this.patchProps(props);
|
|
676
743
|
}
|
|
744
|
+
// Private method to map SSG node tree
|
|
677
745
|
mapSSGNodeTree(parent) {
|
|
678
746
|
this.treeMap.set(0, parent);
|
|
679
|
-
|
|
680
|
-
var _a;
|
|
681
|
-
if (node.nodeType !== Node.DOCUMENT_FRAGMENT_NODE) {
|
|
682
|
-
if (node.nodeType === Node.COMMENT_NODE) {
|
|
683
|
-
const [type, index] = ((_a = node.textContent) == null ? void 0 : _a.split("-")) || "";
|
|
684
|
-
if (0 /* TEXT */ === +type && +index === this.componentIndex) {
|
|
685
|
-
const textNode = node.nextSibling;
|
|
686
|
-
this.treeMap.set(+index, textNode);
|
|
687
|
-
}
|
|
688
|
-
} else if (node.nodeType !== Node.TEXT_NODE) {
|
|
689
|
-
const { ci = "-1", hk } = (node == null ? void 0 : node.dataset) || {};
|
|
690
|
-
if (hk && +ci === this.componentIndex) {
|
|
691
|
-
this.treeMap.set(+hk, node);
|
|
692
|
-
}
|
|
693
|
-
}
|
|
694
|
-
}
|
|
695
|
-
let child = node.firstChild;
|
|
696
|
-
while (child) {
|
|
697
|
-
walk(child);
|
|
698
|
-
child = child.nextSibling;
|
|
699
|
-
}
|
|
700
|
-
};
|
|
701
|
-
walk(parent);
|
|
747
|
+
this.walkNodeTree(parent, this.handleSSGNode.bind(this));
|
|
702
748
|
}
|
|
749
|
+
// Private method to map node tree
|
|
703
750
|
mapNodeTree(parent, tree) {
|
|
704
751
|
let index = 1;
|
|
705
752
|
this.treeMap.set(0, parent);
|
|
706
|
-
const
|
|
753
|
+
const handleNode = (node) => {
|
|
707
754
|
if (node.nodeType !== Node.DOCUMENT_FRAGMENT_NODE) {
|
|
708
755
|
this.treeMap.set(index++, node);
|
|
709
756
|
}
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
757
|
+
};
|
|
758
|
+
this.walkNodeTree(tree, handleNode);
|
|
759
|
+
}
|
|
760
|
+
// Private method to walk through the node tree
|
|
761
|
+
walkNodeTree(node, handler) {
|
|
762
|
+
if (node.nodeType !== Node.DOCUMENT_FRAGMENT_NODE) {
|
|
763
|
+
handler(node);
|
|
764
|
+
}
|
|
765
|
+
let child = node.firstChild;
|
|
766
|
+
while (child) {
|
|
767
|
+
this.walkNodeTree(child, handler);
|
|
768
|
+
child = child.nextSibling;
|
|
769
|
+
}
|
|
770
|
+
}
|
|
771
|
+
// Private method to handle SSG nodes
|
|
772
|
+
handleSSGNode(node) {
|
|
773
|
+
var _a;
|
|
774
|
+
if (node.nodeType === Node.COMMENT_NODE) {
|
|
775
|
+
const [type, index] = ((_a = node.textContent) == null ? void 0 : _a.split("-")) || [];
|
|
776
|
+
if (0 /* TEXT */ === +type && +index === this.componentIndex) {
|
|
777
|
+
const textNode = node.nextSibling;
|
|
778
|
+
this.treeMap.set(+index, textNode);
|
|
779
|
+
}
|
|
780
|
+
} else if (node.nodeType !== Node.TEXT_NODE) {
|
|
781
|
+
const { ci = "-1", hk } = (node == null ? void 0 : node.dataset) || {};
|
|
782
|
+
if (hk && +ci === this.componentIndex) {
|
|
783
|
+
this.treeMap.set(+hk, node);
|
|
714
784
|
}
|
|
785
|
+
}
|
|
786
|
+
}
|
|
787
|
+
// Method to patch props onto the node
|
|
788
|
+
patchProps(props) {
|
|
789
|
+
if (!props) return;
|
|
790
|
+
Object.entries(props).forEach(([key, value]) => {
|
|
791
|
+
const index = Number(key);
|
|
792
|
+
const node = this.treeMap.get(index);
|
|
793
|
+
if (node) {
|
|
794
|
+
this.patchProp(key, node, value, index === 0);
|
|
795
|
+
}
|
|
796
|
+
});
|
|
797
|
+
this.props = props;
|
|
798
|
+
}
|
|
799
|
+
// Private method to patch a single prop
|
|
800
|
+
patchProp(key, node, props, isRoot) {
|
|
801
|
+
if (!props) return;
|
|
802
|
+
Object.entries(props).forEach(([attr, value]) => {
|
|
803
|
+
if (attr === CHILDREN_PROP && value) {
|
|
804
|
+
this.patchChildren(key, node, value, isRoot);
|
|
805
|
+
} else if (attr === "ref") {
|
|
806
|
+
props[attr].value = node;
|
|
807
|
+
} else if (startsWith(attr, "on")) {
|
|
808
|
+
this.patchEventListener(key, node, attr, value);
|
|
809
|
+
} else {
|
|
810
|
+
this.patchAttribute(key, node, attr, value);
|
|
811
|
+
}
|
|
812
|
+
});
|
|
813
|
+
}
|
|
814
|
+
// Private method to patch children
|
|
815
|
+
patchChildren(key, node, children, isRoot) {
|
|
816
|
+
if (!isArray(children)) {
|
|
817
|
+
const trackKey = `${key}:${CHILDREN_PROP}:0`;
|
|
818
|
+
const track = this.getNodeTrack(trackKey, true, isRoot);
|
|
819
|
+
this.patchChild(track, node, children, null);
|
|
820
|
+
} else {
|
|
821
|
+
children.filter(Boolean).forEach((item, index) => {
|
|
822
|
+
var _a;
|
|
823
|
+
const [child, path] = isArray(item) ? item : [item, null];
|
|
824
|
+
const before = isNil(path) ? null : (_a = this.treeMap.get(path)) != null ? _a : null;
|
|
825
|
+
const trackKey = `${key}:${CHILDREN_PROP}:${index}`;
|
|
826
|
+
const track = this.getNodeTrack(trackKey, true, isRoot);
|
|
827
|
+
this.patchChild(track, node, child, before);
|
|
828
|
+
});
|
|
829
|
+
}
|
|
830
|
+
}
|
|
831
|
+
// Private method to patch event listeners
|
|
832
|
+
patchEventListener(key, node, attr, listener) {
|
|
833
|
+
const eventName = attr.slice(2).toLowerCase();
|
|
834
|
+
const track = this.getNodeTrack(`${key}:${attr}`);
|
|
835
|
+
track.cleanup = addEventListener(node, eventName, listener);
|
|
836
|
+
}
|
|
837
|
+
// Private method to patch attributes
|
|
838
|
+
patchAttribute(key, element, attr, value) {
|
|
839
|
+
var _a, _b;
|
|
840
|
+
const updateKey = `update${capitalizeFirstLetter(attr)}`;
|
|
841
|
+
if (this.bindValueKeys.includes(attr)) {
|
|
842
|
+
return;
|
|
843
|
+
}
|
|
844
|
+
if ((_a = this.props) == null ? void 0 : _a[updateKey]) {
|
|
845
|
+
this.bindValueKeys.push(updateKey);
|
|
846
|
+
}
|
|
847
|
+
const track = this.getNodeTrack(`${key}:${attr}`);
|
|
848
|
+
const triggerValue = isSignal(value) ? value : useSignal(value);
|
|
849
|
+
setAttribute(element, attr, triggerValue.value);
|
|
850
|
+
const cleanup = useEffect(() => {
|
|
851
|
+
triggerValue.value = isSignal(value) ? value.value : value;
|
|
852
|
+
setAttribute(element, attr, triggerValue.value);
|
|
853
|
+
});
|
|
854
|
+
let cleanupBind;
|
|
855
|
+
if (((_b = this.props) == null ? void 0 : _b[updateKey]) && !isComponent(attr)) {
|
|
856
|
+
cleanupBind = bindNode(element, (value2) => {
|
|
857
|
+
var _a2;
|
|
858
|
+
(_a2 = this.props) == null ? void 0 : _a2[updateKey](value2);
|
|
859
|
+
});
|
|
860
|
+
}
|
|
861
|
+
track.cleanup = () => {
|
|
862
|
+
cleanup && cleanup();
|
|
863
|
+
cleanupBind && cleanupBind();
|
|
715
864
|
};
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
/**
|
|
719
|
-
* Get a NodeTrack from the trackMap. If the track is not in the trackMap, create a new one.
|
|
720
|
-
* Then, call the cleanup function to remove any previously registered hooks.
|
|
721
|
-
* @param trackKey the key of the node track to get.
|
|
722
|
-
* @param trackLastNodes if true, the track will record the last nodes it has rendered.
|
|
723
|
-
* @param isRoot if true, the track will be treated as a root track.
|
|
724
|
-
* @returns the NodeTrack, cleaned up and ready to use.
|
|
725
|
-
*/
|
|
865
|
+
}
|
|
866
|
+
// Private method to get or create a NodeTrack
|
|
726
867
|
getNodeTrack(trackKey, trackLastNodes, isRoot) {
|
|
727
868
|
var _a;
|
|
728
869
|
let track = this.trackMap.get(trackKey);
|
|
@@ -740,131 +881,67 @@ var TemplateNode = class {
|
|
|
740
881
|
(_a = track.cleanup) == null ? void 0 : _a.call(track);
|
|
741
882
|
return track;
|
|
742
883
|
}
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
884
|
+
// Private method to patch a child node
|
|
885
|
+
patchChild(track, parent, child, before) {
|
|
886
|
+
if (isFunction(child)) {
|
|
887
|
+
track.cleanup = useEffect(() => {
|
|
888
|
+
const nextNodes = coerceArray(child()).map(coerceNode);
|
|
889
|
+
if (renderContext.isSSR) {
|
|
890
|
+
track.lastNodes = this.reconcileChildren(parent, nextNodes, before);
|
|
750
891
|
} else {
|
|
751
|
-
|
|
752
|
-
var _a;
|
|
753
|
-
const [child, path] = isArray(item) ? item : [item, null];
|
|
754
|
-
const before = isNil(path) ? null : (_a = this.treeMap.get(path)) != null ? _a : null;
|
|
755
|
-
const trackKey = `${key}:${attr}:${index}`;
|
|
756
|
-
const track = this.getNodeTrack(trackKey, true, isRoot);
|
|
757
|
-
patchChild(track, node, child, before);
|
|
758
|
-
});
|
|
892
|
+
track.lastNodes = patchChildren(parent, track.lastNodes, nextNodes, before);
|
|
759
893
|
}
|
|
760
|
-
}
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
const
|
|
764
|
-
const
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
break;
|
|
771
|
-
}
|
|
772
|
-
if (props[updateKey]) {
|
|
773
|
-
this.bindValueKeys.push(updateKey);
|
|
774
|
-
}
|
|
775
|
-
const track = this.getNodeTrack(`${key}:${attr}`);
|
|
776
|
-
const val = props[attr];
|
|
777
|
-
const triggerValue = isSignal(val) ? val : useSignal(val);
|
|
778
|
-
patchAttribute(track, node, attr, triggerValue.value);
|
|
779
|
-
const cleanup = useEffect(() => {
|
|
780
|
-
triggerValue.value = isSignal(val) ? val.value : val;
|
|
781
|
-
patchAttribute(track, node, attr, triggerValue.value);
|
|
782
|
-
});
|
|
783
|
-
let cleanupBind;
|
|
784
|
-
if (props[updateKey] && !isComponent(attr)) {
|
|
785
|
-
cleanupBind = bindNode(node, (value) => {
|
|
786
|
-
props[updateKey](value);
|
|
787
|
-
});
|
|
894
|
+
});
|
|
895
|
+
} else {
|
|
896
|
+
coerceArray(child).forEach((node, index) => {
|
|
897
|
+
const newNode = coerceNode(node);
|
|
898
|
+
const key = getKey(newNode, index);
|
|
899
|
+
if (renderContext.isSSR) {
|
|
900
|
+
track.lastNodes = this.reconcileChildren(parent, [newNode], before);
|
|
901
|
+
} else {
|
|
902
|
+
track.lastNodes.set(key, newNode);
|
|
903
|
+
insertChild(parent, newNode, before);
|
|
788
904
|
}
|
|
789
|
-
|
|
790
|
-
cleanup && cleanup();
|
|
791
|
-
cleanupBind && cleanupBind();
|
|
792
|
-
};
|
|
793
|
-
}
|
|
905
|
+
});
|
|
794
906
|
}
|
|
795
907
|
}
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
} else {
|
|
804
|
-
track.lastNodes = patchChildren(parent, track.lastNodes, nextNodes, before);
|
|
908
|
+
// Private method to reconcile children nodes
|
|
909
|
+
reconcileChildren(parent, nextNodes, before) {
|
|
910
|
+
const result = /* @__PURE__ */ new Map();
|
|
911
|
+
const textNodes = Array.from(parent.childNodes).filter(
|
|
912
|
+
(node) => {
|
|
913
|
+
var _a, _b;
|
|
914
|
+
return node.nodeType === Node.TEXT_NODE && ((_a = node.previousSibling) == null ? void 0 : _a.nodeType) === Node.COMMENT_NODE && ((_b = node.nextSibling) == null ? void 0 : _b.nodeType) === Node.COMMENT_NODE;
|
|
805
915
|
}
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
916
|
+
);
|
|
917
|
+
nextNodes.forEach((node, index) => {
|
|
918
|
+
const key = getKey(node, index);
|
|
919
|
+
if (node.nodeType === Node.TEXT_NODE) {
|
|
920
|
+
textNodes.forEach((ne) => {
|
|
921
|
+
if (node.textContent === ne.textContent) {
|
|
922
|
+
parent.replaceChild(node, ne);
|
|
923
|
+
}
|
|
924
|
+
});
|
|
814
925
|
} else {
|
|
815
|
-
|
|
816
|
-
insertChild(parent, newNode, before);
|
|
926
|
+
insertChild(parent, node, before);
|
|
817
927
|
}
|
|
928
|
+
result.set(key, node);
|
|
818
929
|
});
|
|
930
|
+
return result;
|
|
819
931
|
}
|
|
820
|
-
}
|
|
821
|
-
function reconcileChildren(parent, nextNodes, before) {
|
|
822
|
-
const result = /* @__PURE__ */ new Map();
|
|
823
|
-
const textNodes = Array.from(parent.childNodes).filter(
|
|
824
|
-
(node) => {
|
|
825
|
-
var _a, _b;
|
|
826
|
-
return node.nodeType === Node.TEXT_NODE && ((_a = node.previousSibling) == null ? void 0 : _a.nodeType) === Node.COMMENT_NODE && ((_b = node.nextSibling) == null ? void 0 : _b.nodeType) === Node.COMMENT_NODE;
|
|
827
|
-
}
|
|
828
|
-
);
|
|
829
|
-
nextNodes.forEach((node, index) => {
|
|
830
|
-
const key = getKey(node, index);
|
|
831
|
-
if (node.nodeType === Node.TEXT_NODE) {
|
|
832
|
-
textNodes.forEach((ne) => {
|
|
833
|
-
if (node.textContent === ne.textContent) {
|
|
834
|
-
parent.replaceChild(node, ne);
|
|
835
|
-
}
|
|
836
|
-
});
|
|
837
|
-
} else {
|
|
838
|
-
insertChild(parent, node, before);
|
|
839
|
-
}
|
|
840
|
-
result.set(key, node);
|
|
841
|
-
});
|
|
842
|
-
return result;
|
|
843
|
-
}
|
|
844
|
-
function patchAttribute(track, node, attr, data) {
|
|
845
|
-
const element = node;
|
|
846
|
-
if (!element.setAttribute) {
|
|
847
|
-
return;
|
|
848
|
-
}
|
|
849
|
-
if (isFunction(data)) {
|
|
850
|
-
track.cleanup = useEffect(() => {
|
|
851
|
-
setAttribute(element, attr, data());
|
|
852
|
-
});
|
|
853
|
-
} else {
|
|
854
|
-
setAttribute(element, attr, data);
|
|
855
|
-
}
|
|
856
|
-
}
|
|
932
|
+
};
|
|
857
933
|
|
|
858
934
|
// src/jsx-renderer.ts
|
|
859
935
|
function h(template, props, key) {
|
|
860
936
|
if (isString(template)) {
|
|
861
937
|
if (isHtmlTagName(template)) {
|
|
862
|
-
|
|
863
|
-
props = {
|
|
864
|
-
|
|
865
|
-
|
|
938
|
+
const htmlTemplate = convertToHtmlTag(template);
|
|
939
|
+
props = { [SINGLE_PROP_KEY]: props };
|
|
940
|
+
return new TemplateNode(createTemplate(htmlTemplate), props, key);
|
|
941
|
+
} else if (template === EMPTY_TEMPLATE) {
|
|
942
|
+
props = { [FRAGMENT_PROP_KEY]: props };
|
|
943
|
+
return new TemplateNode(createTemplate(EMPTY_TEMPLATE), props, key);
|
|
866
944
|
}
|
|
867
|
-
template = createTemplate(template);
|
|
868
945
|
}
|
|
869
946
|
return isFunction(template) ? new ComponentNode(template, props, key) : new TemplateNode(template, props, key);
|
|
870
947
|
}
|
|
@@ -880,19 +957,17 @@ function createTemplate(html) {
|
|
|
880
957
|
return template;
|
|
881
958
|
}
|
|
882
959
|
function Fragment(props) {
|
|
883
|
-
return h(
|
|
884
|
-
children:
|
|
960
|
+
return h(EMPTY_TEMPLATE, {
|
|
961
|
+
children: isArray(props.children) ? props.children.filter(Boolean) : [props.children]
|
|
885
962
|
});
|
|
886
963
|
}
|
|
887
964
|
function onMount(cb) {
|
|
888
|
-
var _a;
|
|
889
965
|
assertInsideComponent("onMounted");
|
|
890
|
-
|
|
966
|
+
LifecycleContext.ref && LifecycleContext.ref.addHook("mounted", cb);
|
|
891
967
|
}
|
|
892
968
|
function onDestroy(cb) {
|
|
893
|
-
var _a;
|
|
894
969
|
assertInsideComponent("onDestroy");
|
|
895
|
-
|
|
970
|
+
LifecycleContext.ref && LifecycleContext.ref.addHook("destroy", cb);
|
|
896
971
|
}
|
|
897
972
|
function assertInsideComponent(hookName, key) {
|
|
898
973
|
if (!LifecycleContext.ref && true) {
|
|
@@ -903,21 +978,19 @@ function assertInsideComponent(hookName, key) {
|
|
|
903
978
|
}
|
|
904
979
|
}
|
|
905
980
|
function useProvide(key, value) {
|
|
906
|
-
var _a;
|
|
907
981
|
assertInsideComponent("useProvide", key);
|
|
908
|
-
|
|
982
|
+
LifecycleContext.ref && LifecycleContext.ref.setContext(key, value);
|
|
909
983
|
}
|
|
910
984
|
function useInject(key, defaultValue) {
|
|
911
985
|
var _a;
|
|
912
986
|
assertInsideComponent("useInject", key);
|
|
913
|
-
return (
|
|
987
|
+
return (_a = LifecycleContext.ref && LifecycleContext.ref.getContext(key)) != null ? _a : defaultValue;
|
|
914
988
|
}
|
|
915
989
|
function useRef() {
|
|
916
|
-
|
|
917
|
-
return ref;
|
|
990
|
+
return shallowSignal(null);
|
|
918
991
|
}
|
|
919
992
|
|
|
920
|
-
// src/
|
|
993
|
+
// src/server.ts
|
|
921
994
|
function renderToString(component, props) {
|
|
922
995
|
renderContext.setSSG();
|
|
923
996
|
const ssrNode = new SSGNode(component, props || {});
|