|
|
|
@ -24,8 +24,14 @@ import { create_attribute, is_custom_element_node, is_element_node } from '../..
|
|
|
|
|
import { error } from '../../../errors.js';
|
|
|
|
|
import { binding_properties } from '../../bindings.js';
|
|
|
|
|
import { regex_starts_with_newline, regex_whitespaces_strict } from '../../patterns.js';
|
|
|
|
|
import { DOMBooleanAttributes, HYDRATION_END, HYDRATION_START } from '../../../../constants.js';
|
|
|
|
|
import {
|
|
|
|
|
DOMBooleanAttributes,
|
|
|
|
|
HYDRATION_END,
|
|
|
|
|
HYDRATION_END_ELSE,
|
|
|
|
|
HYDRATION_START
|
|
|
|
|
} from '../../../../constants.js';
|
|
|
|
|
import { sanitize_template_string } from '../../../utils/sanitize_template_string.js';
|
|
|
|
|
import { BLOCK_CLOSE, BLOCK_CLOSE_ELSE } from '../../../../internal/server/hydration.js';
|
|
|
|
|
|
|
|
|
|
export const block_open = t_string(`<!--${HYDRATION_START}-->`);
|
|
|
|
|
export const block_close = t_string(`<!--${HYDRATION_END}-->`);
|
|
|
|
@ -1499,55 +1505,46 @@ const template_visitors = {
|
|
|
|
|
b.update('++', index, false),
|
|
|
|
|
b.block(each)
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
const close = b.stmt(b.assignment('+=', b.id('$$payload.out'), b.literal(BLOCK_CLOSE)));
|
|
|
|
|
|
|
|
|
|
if (node.fallback) {
|
|
|
|
|
const fallback_stmts = create_block(node, node.fallback.nodes, context);
|
|
|
|
|
fallback_stmts.unshift(
|
|
|
|
|
b.stmt(b.assignment('+=', b.id('$$payload.out'), b.literal('<!ssr:each_else>')))
|
|
|
|
|
);
|
|
|
|
|
const fallback = create_block(node, node.fallback.nodes, context);
|
|
|
|
|
|
|
|
|
|
fallback.push(b.stmt(b.assignment('+=', b.id('$$payload.out'), b.literal(BLOCK_CLOSE_ELSE))));
|
|
|
|
|
|
|
|
|
|
state.template.push(
|
|
|
|
|
t_statement(
|
|
|
|
|
b.if(
|
|
|
|
|
b.binary('!==', b.member(array_id, b.id('length')), b.literal(0)),
|
|
|
|
|
for_loop,
|
|
|
|
|
b.block(fallback_stmts)
|
|
|
|
|
b.block([for_loop, close]),
|
|
|
|
|
b.block(fallback)
|
|
|
|
|
)
|
|
|
|
|
)
|
|
|
|
|
);
|
|
|
|
|
} else {
|
|
|
|
|
state.template.push(t_statement(for_loop));
|
|
|
|
|
state.template.push(t_statement(for_loop), t_statement(close));
|
|
|
|
|
}
|
|
|
|
|
state.template.push(block_close);
|
|
|
|
|
},
|
|
|
|
|
IfBlock(node, context) {
|
|
|
|
|
const state = context.state;
|
|
|
|
|
state.template.push(block_open);
|
|
|
|
|
|
|
|
|
|
// Insert ssr:if:true/false anchors in addition to the other anchors so that
|
|
|
|
|
// the if block can catch hydration mismatches (false on the server, true on the client and vice versa)
|
|
|
|
|
// and continue hydration without having to re-render everything from scratch.
|
|
|
|
|
|
|
|
|
|
const consequent = create_block(node, node.consequent.nodes, context);
|
|
|
|
|
consequent.unshift(
|
|
|
|
|
b.stmt(b.assignment('+=', b.id('$$payload.out'), b.literal('<!ssr:if:true>')))
|
|
|
|
|
);
|
|
|
|
|
const alternate = node.alternate ? create_block(node, node.alternate.nodes, context) : [];
|
|
|
|
|
|
|
|
|
|
const alternate = node.alternate
|
|
|
|
|
? /** @type {import('estree').BlockStatement} */ (context.visit(node.alternate))
|
|
|
|
|
: b.block([]);
|
|
|
|
|
alternate.body.unshift(
|
|
|
|
|
b.stmt(b.assignment('+=', b.id('$$payload.out'), b.literal('<!ssr:if:false>')))
|
|
|
|
|
);
|
|
|
|
|
consequent.push(b.stmt(b.assignment('+=', b.id('$$payload.out'), b.literal(BLOCK_CLOSE))));
|
|
|
|
|
alternate.push(b.stmt(b.assignment('+=', b.id('$$payload.out'), b.literal(BLOCK_CLOSE_ELSE))));
|
|
|
|
|
|
|
|
|
|
state.template.push(
|
|
|
|
|
t_statement(
|
|
|
|
|
b.if(
|
|
|
|
|
/** @type {import('estree').Expression} */ (context.visit(node.test)),
|
|
|
|
|
b.block(/** @type {import('estree').Statement[]} */ (consequent)),
|
|
|
|
|
alternate
|
|
|
|
|
b.block(consequent),
|
|
|
|
|
b.block(alternate)
|
|
|
|
|
)
|
|
|
|
|
)
|
|
|
|
|
);
|
|
|
|
|
state.template.push(block_close);
|
|
|
|
|
},
|
|
|
|
|
AwaitBlock(node, context) {
|
|
|
|
|
const state = context.state;
|
|
|
|
|