mikuru 1.0.23 → 1.0.24
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/CHANGELOG.md +11 -0
- package/README.md +11 -10
- package/dist/compiler/compatDiagnostics.d.ts +8 -0
- package/dist/compiler/compatDiagnostics.js +45 -0
- package/dist/compiler/compatDiagnostics.js.map +1 -0
- package/dist/compiler/compile.js +29 -16
- package/dist/compiler/compile.js.map +1 -1
- package/dist/compiler/compileHydration.js +31 -18
- package/dist/compiler/compileHydration.js.map +1 -1
- package/dist/compiler/compileSsr.js +27 -14
- package/dist/compiler/compileSsr.js.map +1 -1
- package/dist/compiler/generate.d.ts +17 -1
- package/dist/compiler/generate.js +160 -8
- package/dist/compiler/generate.js.map +1 -1
- package/dist/compiler/generateHydration.js +185 -30
- package/dist/compiler/generateHydration.js.map +1 -1
- package/dist/compiler/generateSsr.js +14 -4
- package/dist/compiler/generateSsr.js.map +1 -1
- package/dist/compiler/parseTemplate.js +18 -5
- package/dist/compiler/parseTemplate.js.map +1 -1
- package/dist/compiler/types.d.ts +1 -0
- package/dist/index.d.ts +2 -2
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/router/index.js +27 -3
- package/dist/router/index.js.map +1 -1
- package/dist/runtime/asyncComponent.js +24 -4
- package/dist/runtime/asyncComponent.js.map +1 -1
- package/dist/runtime/devtools.d.ts +16 -0
- package/dist/runtime/devtools.js +21 -0
- package/dist/runtime/devtools.js.map +1 -1
- package/dist/runtime/index.d.ts +2 -2
- package/dist/runtime/index.js +1 -1
- package/dist/runtime/index.js.map +1 -1
- package/dist/server.js +16 -6
- package/dist/server.js.map +1 -1
- package/package.json +1 -1
- package/templates/basic/src/App.mikuru +1 -1
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { createCompileError } from "./errors.js";
|
|
2
|
+
import { createScopeAttr, generateChildren as generateDomChildren, generateNode as generateDomNode, withoutForAttrs as withoutDomForAttrs } from "./generate.js";
|
|
2
3
|
import { compileTemplateExpression, parseForExpression, validateAssignableExpression } from "./parseExpression.js";
|
|
3
4
|
export function generateHydration(descriptor, root, options = {}) {
|
|
4
5
|
const context = {
|
|
@@ -8,12 +9,13 @@ export function generateHydration(descriptor, root, options = {}) {
|
|
|
8
9
|
source: descriptor.source,
|
|
9
10
|
filename: descriptor.filename
|
|
10
11
|
};
|
|
12
|
+
context.scopeAttr = descriptor.styleScoped ? createScopeAttr(descriptor) : undefined;
|
|
11
13
|
const script = splitScript(descriptor.script ?? "");
|
|
12
14
|
if (options.includeImports !== false) {
|
|
13
15
|
for (const importLine of script.imports) {
|
|
14
16
|
emit(context, 0, importLine);
|
|
15
17
|
}
|
|
16
|
-
emit(context, 0, "import { effect, setAttribute, unwrap } from \"mikuru/runtime\";");
|
|
18
|
+
emit(context, 0, "import { effect, ref, setAttribute, unwrap } from \"mikuru/runtime\";");
|
|
17
19
|
emit(context, 0, "");
|
|
18
20
|
}
|
|
19
21
|
emit(context, 0, "export function hydrate(target, props = {}) {");
|
|
@@ -22,7 +24,15 @@ export function generateHydration(descriptor, root, options = {}) {
|
|
|
22
24
|
emit(context, 1, "const __mikuru_afterUnmount = [];");
|
|
23
25
|
emit(context, 1, "const __mikuru_mounted = [];");
|
|
24
26
|
emit(context, 1, "const __mikuru_context = { parent: props.__mikuru_context, provides: new Map(), errorHandler: props.__mikuru_context?.errorHandler, ...__mikuru_componentInfo };");
|
|
25
|
-
emit(context, 1, "const
|
|
27
|
+
emit(context, 1, "const __mikuru_errorInfo = (phase) => ({ ...__mikuru_componentInfo, phase });");
|
|
28
|
+
emit(context, 1, "const __mikuru_reportError = (error, errorHandler = __mikuru_context.errorHandler, phase = \"runtime\") => { if (typeof errorHandler === \"function\") { Promise.resolve().then(() => errorHandler(error, __mikuru_errorInfo(phase))); return; } setTimeout(() => { throw error; }); };");
|
|
29
|
+
emit(context, 1, "const __mikuru_try = (fn, errorHandler, phase) => { try { return fn(); } catch (error) { __mikuru_reportError(error, errorHandler, phase); } };");
|
|
30
|
+
emit(context, 1, "const __mikuru_memoEqual = (previous, next) => Array.isArray(previous) && Array.isArray(next) && previous.length === next.length && previous.every((value, index) => Object.is(value, next[index]));");
|
|
31
|
+
emit(context, 1, "const __mikuru_guardEventHandler = (fn, errorHandler = __mikuru_context.errorHandler) => (...args) => __mikuru_try(() => fn(...args), errorHandler, \"event\");");
|
|
32
|
+
emit(context, 1, "const __mikuru_runCleanup = (cleanups) => { for (const cleanup of cleanups.splice(0).reverse()) __mikuru_try(cleanup, undefined, \"cleanup\"); };");
|
|
33
|
+
emit(context, 1, "const __mikuru_removeNode = (node) => { if (node?.parentNode) node.remove(); };");
|
|
34
|
+
emit(context, 1, "const __mikuru_applyTransitionEnter = () => {};");
|
|
35
|
+
emit(context, 1, "const __mikuru_applyTransitionMove = () => {};");
|
|
26
36
|
emit(context, 1, "const __mikuru_previousRegistrar = globalThis.__mikuru_currentRegistrar;");
|
|
27
37
|
emit(context, 1, "globalThis.__mikuru_currentRegistrar = {");
|
|
28
38
|
emit(context, 2, "registerMounted: (fn) => __mikuru_mounted.push(fn),");
|
|
@@ -40,8 +50,8 @@ export function generateHydration(descriptor, root, options = {}) {
|
|
|
40
50
|
emit(context, 1, "const __mikuru_emitDebug = (type, payload) => { const hook = globalThis.__MIKURU_DEVTOOLS__; if (!hook) return; const event = { type, timestamp: Date.now(), payload }; hook.events ??= []; hook.events.push(event); if (typeof hook.emit === \"function\") hook.emit(event); for (const listener of hook.listeners ?? []) { try { listener(event); } catch (error) { setTimeout(() => { throw error; }); } } };");
|
|
41
51
|
emit(context, 1, "const __mikuru_domPath = (node) => { if (!node) return \"missing\"; const parts = []; for (let cursor = node.nodeType === 1 ? node : node.parentElement; cursor && cursor.nodeType === 1; cursor = cursor.parentElement) { const tag = cursor.tagName.toLowerCase(); const siblings = cursor.parentElement ? Array.from(cursor.parentElement.children).filter((child) => child.tagName === cursor.tagName) : []; const index = siblings.length > 1 ? `:nth-of-type(${siblings.indexOf(cursor) + 1})` : \"\"; parts.unshift(`${tag}${index}`); } return parts.join(\" > \") || __mikuru_describeNode(node); };");
|
|
42
52
|
emit(context, 1, "const __mikuru_inferDiagnostic = (message) => { const action = message.includes(\"falling back to mount\") ? \"mount-fallback\" : message.includes(\"remounting\") ? \"remount\" : message.includes(\"Recovery was disabled\") || message.endsWith(\".\") ? \"warn-only\" : \"sync-dom\"; const kind = message.startsWith(\"Root mismatch\") ? \"root\" : message.startsWith(\"Element mismatch\") ? \"element\" : message.startsWith(\"Text mismatch\") || message.startsWith(\"Text content mismatch\") ? \"text\" : message.startsWith(\"Attribute mismatch\") ? \"attribute\" : message.startsWith(\"v-model\") ? \"model\" : message.startsWith(\"Extra DOM nodes\") ? \"extra-node\" : message.startsWith(\"Teleport\") ? \"teleport\" : message.startsWith(\"Component\") || message.startsWith(\"Dynamic component\") ? \"component\" : message.startsWith(\"Branch\") ? \"branch\" : message.startsWith(\"List\") ? \"list\" : \"hydration\"; const match = message.match(/expected\\s+(.+?),\\s+got\\s+(.+?)(?:[.;]|$)/); return { action, kind, expected: match?.[1], actual: match?.[2] }; };");
|
|
43
|
-
emit(context, 1, "const __mikuru_hydrationDiagnostic = (message, details = {}) => { const inferred = __mikuru_inferDiagnostic(message); const node = details.node; const diagnostic = { ...__mikuru_componentInfo, phase: \"hydration\", message, ...inferred, ...details }; delete diagnostic.node; if (!diagnostic.domPath && node) diagnostic.domPath = __mikuru_domPath(node); return diagnostic; };");
|
|
44
|
-
emit(context, 1, "const __mikuru_warn = (message, details = {}) => { const diagnostic = __mikuru_hydrationDiagnostic(message, details); __mikuru_emitDebug(\"hydration:warning\", diagnostic); if (typeof console !== \"undefined\" && console.warn) console.warn(`[Mikuru hydration] ${message} (phase: ${diagnostic.phase}, component: ${diagnostic.component}, file: ${diagnostic.filename})`); };");
|
|
53
|
+
emit(context, 1, "const __mikuru_hydrationDiagnostic = (message, details = {}) => { const inferred = __mikuru_inferDiagnostic(message); const node = details.node; const diagnostic = { ...__mikuru_componentInfo, source: \"hydration\", level: \"warning\", phase: \"hydration\", message, ...inferred, ...details }; delete diagnostic.node; if (!diagnostic.domPath && node) diagnostic.domPath = __mikuru_domPath(node); return diagnostic; };");
|
|
54
|
+
emit(context, 1, "const __mikuru_warn = (message, details = {}) => { const diagnostic = __mikuru_hydrationDiagnostic(message, details); __mikuru_emitDebug(\"hydration:warning\", { ...diagnostic, diagnostic }); if (typeof console !== \"undefined\" && console.warn) console.warn(`[Mikuru hydration] ${message} (phase: ${diagnostic.phase}, component: ${diagnostic.component}, file: ${diagnostic.filename})`); };");
|
|
45
55
|
emit(context, 1, "const __mikuru_describeNode = (node) => { if (!node) return \"missing\"; if (node.nodeType === 1) return `<${node.tagName?.toLowerCase?.() ?? \"element\"}>`; if (node.nodeType === 3) return `text(${JSON.stringify(node.nodeValue ?? \"\")})`; if (node.nodeType === 8) return `comment(${JSON.stringify(node.nodeValue ?? \"\")})`; return `nodeType(${node.nodeType})`; };");
|
|
46
56
|
emit(context, 1, "const __mikuru_restoreRegistrar = () => { if (__mikuru_previousRegistrar === undefined) { delete globalThis.__mikuru_currentRegistrar; } else { globalThis.__mikuru_currentRegistrar = __mikuru_previousRegistrar; } };");
|
|
47
57
|
emit(context, 1, "const __mikuru_recovery = {};");
|
|
@@ -158,43 +168,52 @@ function hydrateChildren(context, rawChildren, parentVar, indent) {
|
|
|
158
168
|
const children = rawChildren.filter(isHydratableNode);
|
|
159
169
|
const domIndexVar = nextName(context, "domIndex");
|
|
160
170
|
emit(context, indent, `let ${domIndexVar} = 0;`);
|
|
161
|
-
children.
|
|
171
|
+
for (let index = 0; index < children.length; index += 1) {
|
|
172
|
+
const child = children[index];
|
|
162
173
|
if (child.type === "element" && child.tag === "Teleport") {
|
|
163
174
|
hydrateTeleportAtIndex(context, child, parentVar, domIndexVar, indent);
|
|
164
|
-
|
|
175
|
+
continue;
|
|
165
176
|
}
|
|
166
177
|
if (child.type === "element" && child.tag === "component") {
|
|
167
178
|
hydrateDynamicComponentAtIndex(context, child, parentVar, domIndexVar, indent);
|
|
168
|
-
|
|
179
|
+
continue;
|
|
169
180
|
}
|
|
170
181
|
if (child.type === "element" && child.tag === "KeepAlive") {
|
|
171
182
|
hydrateKeepAliveAtIndex(context, child, parentVar, domIndexVar, indent);
|
|
172
|
-
|
|
183
|
+
continue;
|
|
173
184
|
}
|
|
174
185
|
if (child.type === "element" && child.tag === "AsyncBoundary") {
|
|
175
186
|
hydrateAsyncBoundaryAtIndex(context, child, parentVar, domIndexVar, indent);
|
|
176
|
-
|
|
187
|
+
continue;
|
|
177
188
|
}
|
|
178
189
|
if (child.type === "element" && child.tag === "ErrorBoundary") {
|
|
179
190
|
hydrateErrorBoundaryAtIndex(context, child, parentVar, domIndexVar, indent);
|
|
180
|
-
|
|
191
|
+
continue;
|
|
181
192
|
}
|
|
182
193
|
if (child.type === "element" && child.tag === "TransitionGroup") {
|
|
183
194
|
hydrateTransitionGroupAtIndex(context, child, parentVar, domIndexVar, indent);
|
|
184
|
-
|
|
195
|
+
continue;
|
|
185
196
|
}
|
|
186
197
|
if (child.type === "element" && child.tag === "Transition") {
|
|
187
198
|
hydrateTransitionAtIndex(context, child, parentVar, domIndexVar, indent);
|
|
188
|
-
|
|
199
|
+
continue;
|
|
189
200
|
}
|
|
190
201
|
if (child.type === "element" && getAttr(child, "v-if") && !getAttr(child, "v-pre")) {
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
202
|
+
const { branches, nextIndex } = collectIfBranches(children, index);
|
|
203
|
+
hydrateIfChain(context, branches, parentVar, domIndexVar, indent);
|
|
204
|
+
index = nextIndex - 1;
|
|
205
|
+
continue;
|
|
206
|
+
}
|
|
207
|
+
if (child.type === "element" && (getAttr(child, "v-else-if") || getAttr(child, "v-else"))) {
|
|
208
|
+
continue;
|
|
194
209
|
}
|
|
195
210
|
if (child.type === "element" && getAttr(child, "v-for") && !getAttr(child, "v-pre")) {
|
|
196
211
|
hydrateFor(context, child, parentVar, domIndexVar, indent, domIndexVar);
|
|
197
|
-
|
|
212
|
+
continue;
|
|
213
|
+
}
|
|
214
|
+
if (child.type === "element" && child.tag === "template") {
|
|
215
|
+
hydrateFragmentChildrenAtIndex(context, child.children, parentVar, domIndexVar, indent);
|
|
216
|
+
continue;
|
|
198
217
|
}
|
|
199
218
|
const childVar = nextName(context, "node");
|
|
200
219
|
emit(context, indent, `const ${childVar} = ${parentVar}.childNodes[${domIndexVar}];`);
|
|
@@ -212,7 +231,7 @@ function hydrateChildren(context, rawChildren, parentVar, indent) {
|
|
|
212
231
|
emit(context, indent, "}");
|
|
213
232
|
}
|
|
214
233
|
emit(context, indent, `${domIndexVar} += 1;`);
|
|
215
|
-
}
|
|
234
|
+
}
|
|
216
235
|
emit(context, indent, `if (${parentVar}.childNodes.length > ${domIndexVar}) { __mikuru_warn("Extra DOM nodes after hydration: " + Array.from(${parentVar}.childNodes).slice(${domIndexVar}).map(__mikuru_describeNode).join(", ") + "."); }`);
|
|
217
236
|
}
|
|
218
237
|
function hydrateTeleportAtIndex(context, node, parentVar, domIndex, indent) {
|
|
@@ -271,6 +290,52 @@ function hydrateIf(context, node, parentVar, domIndex, indent) {
|
|
|
271
290
|
emit(context, indent + 1, "__mikuru_recover(\"Branch mismatch: expected no v-if DOM for initial state\");");
|
|
272
291
|
emit(context, indent, "}");
|
|
273
292
|
}
|
|
293
|
+
function hydrateIfChain(context, branches, parentVar, domIndex, indent) {
|
|
294
|
+
branches.forEach((branch, index) => {
|
|
295
|
+
if (index === 0) {
|
|
296
|
+
emit(context, indent, `if (unwrap(${compileHydrationExpression(context, branch.condition ?? "", "v-if")})) {`);
|
|
297
|
+
}
|
|
298
|
+
else if (branch.directive === "v-else-if") {
|
|
299
|
+
emit(context, indent, `else if (unwrap(${compileHydrationExpression(context, branch.condition ?? "", "v-else-if")})) {`);
|
|
300
|
+
}
|
|
301
|
+
else {
|
|
302
|
+
emit(context, indent, "else {");
|
|
303
|
+
}
|
|
304
|
+
hydrateFragmentChildrenAtIndex(context, ifBranchChildren(branch.node), parentVar, domIndex, indent + 1);
|
|
305
|
+
emit(context, indent, "}");
|
|
306
|
+
});
|
|
307
|
+
}
|
|
308
|
+
function ifBranchChildren(node) {
|
|
309
|
+
if (node.tag === "template") {
|
|
310
|
+
return node.children;
|
|
311
|
+
}
|
|
312
|
+
return [withoutAttrs(node, ["v-if", "v-else-if", "v-else"])];
|
|
313
|
+
}
|
|
314
|
+
function collectIfBranches(children, startIndex) {
|
|
315
|
+
const first = children[startIndex];
|
|
316
|
+
if (first?.type !== "element") {
|
|
317
|
+
return { branches: [], nextIndex: startIndex + 1 };
|
|
318
|
+
}
|
|
319
|
+
const branches = [{ node: first, condition: getAttrValue(first, "v-if"), directive: "v-if" }];
|
|
320
|
+
let cursor = startIndex + 1;
|
|
321
|
+
while (cursor < children.length) {
|
|
322
|
+
const candidate = children[cursor];
|
|
323
|
+
if (candidate?.type !== "element") {
|
|
324
|
+
break;
|
|
325
|
+
}
|
|
326
|
+
if (getAttr(candidate, "v-else-if")) {
|
|
327
|
+
branches.push({ node: candidate, condition: getAttrValue(candidate, "v-else-if"), directive: "v-else-if" });
|
|
328
|
+
cursor += 1;
|
|
329
|
+
continue;
|
|
330
|
+
}
|
|
331
|
+
if (getAttr(candidate, "v-else")) {
|
|
332
|
+
branches.push({ node: candidate, directive: "v-else" });
|
|
333
|
+
cursor += 1;
|
|
334
|
+
}
|
|
335
|
+
break;
|
|
336
|
+
}
|
|
337
|
+
return { branches, nextIndex: cursor };
|
|
338
|
+
}
|
|
274
339
|
function hydrateFor(context, node, parentVar, domIndex, indent, advanceVar) {
|
|
275
340
|
const attr = getAttr(node, "v-for");
|
|
276
341
|
if (!attr || attr.value === true) {
|
|
@@ -279,6 +344,22 @@ function hydrateFor(context, node, parentVar, domIndex, indent, advanceVar) {
|
|
|
279
344
|
const forExpression = parseForExpression(String(attr.value));
|
|
280
345
|
const listVar = nextName(context, "list");
|
|
281
346
|
const itemVar = nextName(context, "item");
|
|
347
|
+
const startIndexVar = nextName(context, "forStartIndex");
|
|
348
|
+
emit(context, indent, `const ${startIndexVar} = ${domIndex};`);
|
|
349
|
+
if (node.tag === "template") {
|
|
350
|
+
emit(context, indent, `const ${listVar} = Array.from(unwrap(${compileHydrationExpression(context, forExpression.source, "v-for source")}) ?? []);`);
|
|
351
|
+
emit(context, indent, `for (const [__mikuru_index, ${itemVar}] of ${listVar}.entries()) {`);
|
|
352
|
+
emit(context, indent + 1, `const ${forExpression.item} = ${itemVar};`);
|
|
353
|
+
if (forExpression.index) {
|
|
354
|
+
emit(context, indent + 1, `const ${forExpression.index} = __mikuru_index;`);
|
|
355
|
+
}
|
|
356
|
+
withTemplateRefMode(context, "array", () => {
|
|
357
|
+
hydrateFragmentChildrenAtIndex(context, node.children, parentVar, domIndex, indent + 1);
|
|
358
|
+
});
|
|
359
|
+
emit(context, indent, "}");
|
|
360
|
+
emitHydratedForUpdate(context, node, parentVar, startIndexVar, domIndex, indent, forExpression);
|
|
361
|
+
return;
|
|
362
|
+
}
|
|
282
363
|
const childVar = nextName(context, "row");
|
|
283
364
|
const elementCheck = isComponentTag(node.tag)
|
|
284
365
|
? `!${childVar} || ${childVar}.nodeType !== 1`
|
|
@@ -299,6 +380,61 @@ function hydrateFor(context, node, parentVar, domIndex, indent, advanceVar) {
|
|
|
299
380
|
if (advanceVar) {
|
|
300
381
|
emit(context, indent, `${advanceVar} += ${listVar}.length;`);
|
|
301
382
|
}
|
|
383
|
+
emitHydratedForUpdate(context, node, parentVar, startIndexVar, domIndex, indent, forExpression);
|
|
384
|
+
}
|
|
385
|
+
function emitHydratedForUpdate(context, node, parentVar, startIndexVar, endIndexVar, indent, forExpression) {
|
|
386
|
+
const hydratedFirstVar = nextName(context, "forHydratedFirst");
|
|
387
|
+
const hydratedAfterVar = nextName(context, "forHydratedAfter");
|
|
388
|
+
const startAnchorVar = nextName(context, "forUpdateStart");
|
|
389
|
+
const endAnchorVar = nextName(context, "forUpdateEnd");
|
|
390
|
+
const initializedVar = nextName(context, "forInitialized");
|
|
391
|
+
const branchCleanupVar = nextName(context, "forCleanup");
|
|
392
|
+
const stopVar = nextName(context, "stop");
|
|
393
|
+
const sourceVar = nextName(context, "forSource");
|
|
394
|
+
const indexVar = nextName(context, "forIndex");
|
|
395
|
+
const rawItemVar = nextName(context, "forItem");
|
|
396
|
+
emit(context, indent, `const ${hydratedFirstVar} = ${parentVar}.childNodes[${startIndexVar}] ?? null;`);
|
|
397
|
+
emit(context, indent, `const ${hydratedAfterVar} = ${parentVar}.childNodes[${endIndexVar}] ?? null;`);
|
|
398
|
+
emit(context, indent, `let ${startAnchorVar};`);
|
|
399
|
+
emit(context, indent, `let ${endAnchorVar};`);
|
|
400
|
+
emit(context, indent, `let ${initializedVar} = false;`);
|
|
401
|
+
emit(context, indent, `const ${branchCleanupVar} = [];`);
|
|
402
|
+
emit(context, indent, `const ${stopVar} = effect(() => {`);
|
|
403
|
+
emit(context, indent + 1, `const ${sourceVar} = Array.from(unwrap(${compileHydrationExpression(context, forExpression.source, "v-for source")}) ?? []);`);
|
|
404
|
+
emit(context, indent + 1, `if (!${initializedVar}) { ${initializedVar} = true; return; }`);
|
|
405
|
+
emit(context, indent + 1, `if (!${startAnchorVar}) {`);
|
|
406
|
+
emit(context, indent + 2, `${startAnchorVar} = document.createComment("for");`);
|
|
407
|
+
emit(context, indent + 2, `${endAnchorVar} = document.createComment("/for");`);
|
|
408
|
+
emit(context, indent + 2, `${parentVar}.insertBefore(${startAnchorVar}, ${hydratedFirstVar}?.parentNode === ${parentVar} ? ${hydratedFirstVar} : ${hydratedAfterVar});`);
|
|
409
|
+
emit(context, indent + 2, `${parentVar}.insertBefore(${endAnchorVar}, ${hydratedAfterVar});`);
|
|
410
|
+
emit(context, indent + 1, `}`);
|
|
411
|
+
emit(context, indent + 1, `__mikuru_runCleanup(${branchCleanupVar});`);
|
|
412
|
+
emitHydrationRemoveBetween(context, indent + 1, startAnchorVar, endAnchorVar);
|
|
413
|
+
emit(context, indent + 1, `for (let ${indexVar} = 0; ${indexVar} < ${sourceVar}.length; ${indexVar} += 1) {`);
|
|
414
|
+
emit(context, indent + 2, `const ${rawItemVar} = ${sourceVar}[${indexVar}];`);
|
|
415
|
+
emit(context, indent + 2, `const ${forExpression.item} = ${rawItemVar};`);
|
|
416
|
+
if (forExpression.index) {
|
|
417
|
+
emit(context, indent + 2, `const ${forExpression.index} = ${indexVar};`);
|
|
418
|
+
}
|
|
419
|
+
const previousTemplateRefMode = context.templateRefMode;
|
|
420
|
+
context.templateRefMode = "array";
|
|
421
|
+
try {
|
|
422
|
+
if (node.tag === "template") {
|
|
423
|
+
generateDomChildren(context, node.children, parentVar, branchCleanupVar, indent + 2, endAnchorVar);
|
|
424
|
+
}
|
|
425
|
+
else {
|
|
426
|
+
generateDomNode(context, withoutDomForAttrs(node), parentVar, branchCleanupVar, indent + 2, endAnchorVar);
|
|
427
|
+
}
|
|
428
|
+
}
|
|
429
|
+
finally {
|
|
430
|
+
context.templateRefMode = previousTemplateRefMode;
|
|
431
|
+
}
|
|
432
|
+
emit(context, indent + 1, `}`);
|
|
433
|
+
emit(context, indent, `});`);
|
|
434
|
+
emit(context, indent, `__mikuru_cleanup.push(() => {`);
|
|
435
|
+
emit(context, indent + 1, `${stopVar}();`);
|
|
436
|
+
emit(context, indent + 1, `__mikuru_runCleanup(${branchCleanupVar});`);
|
|
437
|
+
emit(context, indent, `});`);
|
|
302
438
|
}
|
|
303
439
|
function hydrateAttrs(context, node, elementVar, indent) {
|
|
304
440
|
const staticClass = getStaticAttrValue(node, "class");
|
|
@@ -848,43 +984,52 @@ function hydrateTransitionGroupElement(context, node, elementVar, indent) {
|
|
|
848
984
|
}
|
|
849
985
|
function hydrateFragmentChildrenAtIndex(context, rawChildren, parentVar, domIndex, indent) {
|
|
850
986
|
const children = rawChildren.filter(isHydratableNode);
|
|
851
|
-
children.
|
|
987
|
+
for (let index = 0; index < children.length; index += 1) {
|
|
988
|
+
const child = children[index];
|
|
852
989
|
if (child.type === "element" && child.tag === "Teleport") {
|
|
853
990
|
hydrateTeleportAtIndex(context, child, parentVar, domIndex, indent);
|
|
854
|
-
|
|
991
|
+
continue;
|
|
855
992
|
}
|
|
856
993
|
if (child.type === "element" && child.tag === "component") {
|
|
857
994
|
hydrateDynamicComponentAtIndex(context, child, parentVar, domIndex, indent);
|
|
858
|
-
|
|
995
|
+
continue;
|
|
859
996
|
}
|
|
860
997
|
if (child.type === "element" && child.tag === "KeepAlive") {
|
|
861
998
|
hydrateKeepAliveAtIndex(context, child, parentVar, domIndex, indent);
|
|
862
|
-
|
|
999
|
+
continue;
|
|
863
1000
|
}
|
|
864
1001
|
if (child.type === "element" && child.tag === "AsyncBoundary") {
|
|
865
1002
|
hydrateAsyncBoundaryAtIndex(context, child, parentVar, domIndex, indent);
|
|
866
|
-
|
|
1003
|
+
continue;
|
|
867
1004
|
}
|
|
868
1005
|
if (child.type === "element" && child.tag === "ErrorBoundary") {
|
|
869
1006
|
hydrateErrorBoundaryAtIndex(context, child, parentVar, domIndex, indent);
|
|
870
|
-
|
|
1007
|
+
continue;
|
|
871
1008
|
}
|
|
872
1009
|
if (child.type === "element" && child.tag === "TransitionGroup") {
|
|
873
1010
|
hydrateTransitionGroupAtIndex(context, child, parentVar, domIndex, indent);
|
|
874
|
-
|
|
1011
|
+
continue;
|
|
875
1012
|
}
|
|
876
1013
|
if (child.type === "element" && child.tag === "Transition") {
|
|
877
1014
|
hydrateTransitionAtIndex(context, child, parentVar, domIndex, indent);
|
|
878
|
-
|
|
1015
|
+
continue;
|
|
879
1016
|
}
|
|
880
1017
|
if (child.type === "element" && getAttr(child, "v-if") && !getAttr(child, "v-pre")) {
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
1018
|
+
const { branches, nextIndex } = collectIfBranches(children, index);
|
|
1019
|
+
hydrateIfChain(context, branches, parentVar, domIndex, indent);
|
|
1020
|
+
index = nextIndex - 1;
|
|
1021
|
+
continue;
|
|
1022
|
+
}
|
|
1023
|
+
if (child.type === "element" && (getAttr(child, "v-else-if") || getAttr(child, "v-else"))) {
|
|
1024
|
+
continue;
|
|
884
1025
|
}
|
|
885
1026
|
if (child.type === "element" && getAttr(child, "v-for") && !getAttr(child, "v-pre")) {
|
|
886
1027
|
hydrateFor(context, child, parentVar, domIndex, indent, domIndex);
|
|
887
|
-
|
|
1028
|
+
continue;
|
|
1029
|
+
}
|
|
1030
|
+
if (child.type === "element" && child.tag === "template") {
|
|
1031
|
+
hydrateFragmentChildrenAtIndex(context, child.children, parentVar, domIndex, indent);
|
|
1032
|
+
continue;
|
|
888
1033
|
}
|
|
889
1034
|
const childVar = nextName(context, "node");
|
|
890
1035
|
emit(context, indent, `const ${childVar} = ${parentVar}.childNodes[${domIndex}];`);
|
|
@@ -902,7 +1047,7 @@ function hydrateFragmentChildrenAtIndex(context, rawChildren, parentVar, domInde
|
|
|
902
1047
|
emit(context, indent, "}");
|
|
903
1048
|
}
|
|
904
1049
|
emit(context, indent, `${domIndex} += 1;`);
|
|
905
|
-
}
|
|
1050
|
+
}
|
|
906
1051
|
}
|
|
907
1052
|
function hydrateComponentProps(context, node, propsVar, indent) {
|
|
908
1053
|
for (const attr of node.attrs) {
|
|
@@ -972,6 +1117,16 @@ function hydrateComponentProps(context, node, propsVar, indent) {
|
|
|
972
1117
|
emit(context, indent, `${propsVar}[${quote(attr.name)}] = ${attr.value === true ? "true" : quote(attr.value)};`);
|
|
973
1118
|
}
|
|
974
1119
|
}
|
|
1120
|
+
function emitHydrationRemoveBetween(context, indent, startVar, endVar) {
|
|
1121
|
+
const currentVar = nextName(context, "current");
|
|
1122
|
+
const nextVarName = nextName(context, "next");
|
|
1123
|
+
emit(context, indent, `let ${currentVar} = ${startVar}.nextSibling;`);
|
|
1124
|
+
emit(context, indent, `while (${currentVar} && ${currentVar} !== ${endVar}) {`);
|
|
1125
|
+
emit(context, indent + 1, `const ${nextVarName} = ${currentVar}.nextSibling;`);
|
|
1126
|
+
emit(context, indent + 1, `__mikuru_removeNode(${currentVar});`);
|
|
1127
|
+
emit(context, indent + 1, `${currentVar} = ${nextVarName};`);
|
|
1128
|
+
emit(context, indent, `}`);
|
|
1129
|
+
}
|
|
975
1130
|
function hydrateEvents(context, node, elementVar, indent) {
|
|
976
1131
|
for (const attr of node.attrs) {
|
|
977
1132
|
const objectEvent = parseObjectOnDirective(attr.name);
|