all tests passing

pull/12215/head
Rich Harris 2 years ago
parent ce5d53e0b3
commit 469c73e43d

@ -943,6 +943,7 @@ function serialize_inline_component(node, component_name, context) {
fn = (node_id) => { fn = (node_id) => {
return b.call( return b.call(
'$.component', '$.component',
node_id,
b.thunk(/** @type {import('estree').Expression} */ (context.visit(node.expression))), b.thunk(/** @type {import('estree').Expression} */ (context.visit(node.expression))),
b.arrow( b.arrow(
[b.id(component_name)], [b.id(component_name)],
@ -1687,12 +1688,24 @@ export const template_visitors = {
flags |= TEMPLATE_USE_IMPORT_NODE; flags |= TEMPLATE_USE_IMPORT_NODE;
} }
if (trimmed[0].type === 'Component' || trimmed[0].type === 'SlotElement') { var first = trimmed[0];
if (first.type === 'SlotElement') {
flags |= TEMPLATE_UNSET_START; flags |= TEMPLATE_UNSET_START;
} }
if (trimmed[0].type === 'RenderTag') { if (first.type === 'Component') {
const callee = unwrap_optional(trimmed[0].expression).callee; // if it's not a `$.component`, mark as unset
const binding = context.state.scope.get(
first.name.includes('.') ? first.name.slice(0, first.name.indexOf('.')) : first.name
);
if (binding === null || binding.kind === 'normal') {
flags |= TEMPLATE_UNSET_START;
}
}
if (first.type === 'RenderTag') {
const callee = unwrap_optional(first.expression).callee;
const is_reactive = const is_reactive =
callee.type !== 'Identifier' || context.state.scope.get(callee.name)?.kind !== 'normal'; callee.type !== 'Identifier' || context.state.scope.get(callee.name)?.kind !== 'normal';
@ -2998,6 +3011,7 @@ export const template_visitors = {
b.stmt( b.stmt(
b.call( b.call(
'$.component', '$.component',
context.state.node,
// TODO use untrack here to not update when binding changes? // TODO use untrack here to not update when binding changes?
// Would align with Svelte 4 behavior, but it's arguably nicer/expected to update this // Would align with Svelte 4 behavior, but it's arguably nicer/expected to update this
b.thunk( b.thunk(

@ -9,14 +9,14 @@ import { block, branch, pause_effect } from '../../reactivity/effects.js';
* @param {(component: C) => import('#client').Dom | void} render_fn * @param {(component: C) => import('#client').Dom | void} render_fn
* @returns {void} * @returns {void}
*/ */
export function component(get_component, render_fn) { export function component(anchor, get_component, render_fn) {
/** @type {C} */ /** @type {C} */
let component; let component;
/** @type {import('#client').Effect | null} */ /** @type {import('#client').Effect | null} */
let effect; let effect;
block(null, 0, () => { block(anchor, 0, () => {
if (component === (component = get_component())) return; if (component === (component = get_component())) return;
if (effect) { if (effect) {

@ -71,6 +71,10 @@ export function template(content, flags) {
assign_nodes(start, end); assign_nodes(start, end);
if (unset) {
current_effect.nodes.anchor = clone.firstChild;
}
return clone; return clone;
}; };
} }
@ -258,11 +262,16 @@ export function comment(flags = 0) {
return hydrate_start; return hydrate_start;
} }
var unset = (flags & TEMPLATE_UNSET_START) !== 0;
var frag = document.createDocumentFragment(); var frag = document.createDocumentFragment();
var anchor = empty(); var anchor = empty();
frag.append(anchor); frag.append(anchor);
assign_nodes((flags & TEMPLATE_UNSET_START) !== 0 ? undefined : null, anchor); assign_nodes(unset ? undefined : null, anchor);
if (unset) {
current_effect.nodes.anchor = anchor;
}
return frag; return frag;
} }

@ -385,7 +385,11 @@ export function destroy_effect(effect, remove_dom = true) {
*/ */
export function get_first_node(effect) { export function get_first_node(effect) {
if (effect.nodes !== null) { if (effect.nodes !== null) {
if (effect.nodes.start != null) { if (effect.nodes.start === undefined) {
return effect.nodes.anchor;
}
if (effect.nodes.start !== null) {
return effect.nodes.start; return effect.nodes.start;
} }
} }

Loading…
Cancel
Save