fix placement of each-else block, and clarify node references in source - fixes #2917

pull/3112/head
Rich Harris 6 years ago
parent 423428f488
commit b1fdcbf576

@ -50,7 +50,6 @@ export default class EachBlockWrapper extends Wrapper {
fragment: FragmentWrapper; fragment: FragmentWrapper;
else?: ElseBlockWrapper; else?: ElseBlockWrapper;
vars: { vars: {
anchor: string;
create_each_block: string; create_each_block: string;
each_block_value: string; each_block_value: string;
get_each_context: string; get_each_context: string;
@ -119,10 +118,7 @@ export default class EachBlockWrapper extends Wrapper {
// optimisation for array literal // optimisation for array literal
fixed_length, fixed_length,
data_length: fixed_length === null ? `${each_block_value}.[✂${c}-${c+4}✂]` : fixed_length, data_length: fixed_length === null ? `${each_block_value}.[✂${c}-${c+4}✂]` : fixed_length,
view_length: fixed_length === null ? `${iterations}.[✂${c}-${c+4}✂]` : fixed_length, view_length: fixed_length === null ? `${iterations}.[✂${c}-${c+4}✂]` : fixed_length
// filled out later
anchor: null
}; };
node.contexts.forEach(prop => { node.contexts.forEach(prop => {
@ -175,10 +171,6 @@ export default class EachBlockWrapper extends Wrapper {
? !this.next.is_dom_node() : ? !this.next.is_dom_node() :
!parent_node || !this.parent.is_dom_node(); !parent_node || !this.parent.is_dom_node();
this.vars.anchor = needs_anchor
? block.get_unique_name(`${this.var}_anchor`)
: (this.next && this.next.var) || 'null';
this.context_props = this.node.contexts.map(prop => `child_ctx.${prop.key.name} = ${attach_head('list[i]', prop.tail)};`); this.context_props = this.node.contexts.map(prop => `child_ctx.${prop.key.name} = ${attach_head('list[i]', prop.tail)};`);
if (this.node.has_binding) this.context_props.push(`child_ctx.${this.vars.each_block_value} = list;`); if (this.node.has_binding) this.context_props.push(`child_ctx.${this.vars.each_block_value} = list;`);
@ -196,10 +188,28 @@ export default class EachBlockWrapper extends Wrapper {
} }
`); `);
const initial_anchor_node = parent_node ? 'null' : 'anchor';
const initial_mount_node = parent_node || '#target';
const update_anchor_node = needs_anchor
? block.get_unique_name(`${this.var}_anchor`)
: (this.next && this.next.var) || 'null';
const update_mount_node = this.get_update_mount_node(update_anchor_node);
const args = {
block,
parent_node,
parent_nodes,
snippet,
initial_anchor_node,
initial_mount_node,
update_anchor_node,
update_mount_node
};
if (this.node.key) { if (this.node.key) {
this.render_keyed(block, parent_node, parent_nodes, snippet); this.render_keyed(args);
} else { } else {
this.render_unkeyed(block, parent_node, parent_nodes, snippet); this.render_unkeyed(args);
} }
if (this.block.has_intro_method || this.block.has_outro_method) { if (this.block.has_intro_method || this.block.has_outro_method) {
@ -210,7 +220,7 @@ export default class EachBlockWrapper extends Wrapper {
if (needs_anchor) { if (needs_anchor) {
block.add_element( block.add_element(
this.vars.anchor, update_anchor_node,
`@empty()`, `@empty()`,
parent_nodes && `@empty()`, parent_nodes && `@empty()`,
parent_node parent_node
@ -232,12 +242,10 @@ export default class EachBlockWrapper extends Wrapper {
block.builders.mount.add_block(deindent` block.builders.mount.add_block(deindent`
if (${each_block_else}) { if (${each_block_else}) {
${each_block_else}.m(${parent_node || '#target'}, null); ${each_block_else}.m(${initial_mount_node}, ${initial_anchor_node});
} }
`); `);
const initial_mount_node = parent_node || `${this.vars.anchor}.parentNode`;
if (this.else.block.has_update_method) { if (this.else.block.has_update_method) {
block.builders.update.add_block(deindent` block.builders.update.add_block(deindent`
if (!${this.vars.data_length} && ${each_block_else}) { if (!${this.vars.data_length} && ${each_block_else}) {
@ -245,7 +253,7 @@ export default class EachBlockWrapper extends Wrapper {
} else if (!${this.vars.data_length}) { } else if (!${this.vars.data_length}) {
${each_block_else} = ${this.else.block.name}(ctx); ${each_block_else} = ${this.else.block.name}(ctx);
${each_block_else}.c(); ${each_block_else}.c();
${each_block_else}.m(${initial_mount_node}, ${this.vars.anchor}); ${each_block_else}.m(${update_mount_node}, ${update_anchor_node});
} else if (${each_block_else}) { } else if (${each_block_else}) {
${each_block_else}.d(1); ${each_block_else}.d(1);
${each_block_else} = null; ${each_block_else} = null;
@ -261,7 +269,7 @@ export default class EachBlockWrapper extends Wrapper {
} else if (!${each_block_else}) { } else if (!${each_block_else}) {
${each_block_else} = ${this.else.block.name}(ctx); ${each_block_else} = ${this.else.block.name}(ctx);
${each_block_else}.c(); ${each_block_else}.c();
${each_block_else}.m(${initial_mount_node}, ${this.vars.anchor}); ${each_block_else}.m(${update_mount_node}, ${update_anchor_node});
} }
`); `);
} }
@ -278,16 +286,28 @@ export default class EachBlockWrapper extends Wrapper {
} }
} }
render_keyed( render_keyed({
block,
parent_node,
parent_nodes,
snippet,
initial_anchor_node,
initial_mount_node,
update_anchor_node,
update_mount_node
}: {
block: Block, block: Block,
parent_node: string, parent_node: string,
parent_nodes: string, parent_nodes: string,
snippet: string snippet: string,
) { initial_anchor_node: string,
initial_mount_node: string,
update_anchor_node: string,
update_mount_node: string
}) {
const { const {
create_each_block, create_each_block,
length, length,
anchor,
iterations, iterations,
view_length view_length
} = this.vars; } = this.vars;
@ -322,10 +342,6 @@ export default class EachBlockWrapper extends Wrapper {
} }
`); `);
const initial_mount_node = parent_node || '#target';
const update_mount_node = this.get_update_mount_node(anchor);
const anchor_node = parent_node ? 'null' : 'anchor';
block.builders.create.add_block(deindent` block.builders.create.add_block(deindent`
for (#i = 0; #i < ${view_length}; #i += 1) ${iterations}[#i].c(); for (#i = 0; #i < ${view_length}; #i += 1) ${iterations}[#i].c();
`); `);
@ -337,7 +353,7 @@ export default class EachBlockWrapper extends Wrapper {
} }
block.builders.mount.add_block(deindent` block.builders.mount.add_block(deindent`
for (#i = 0; #i < ${view_length}; #i += 1) ${iterations}[#i].m(${initial_mount_node}, ${anchor_node}); for (#i = 0; #i < ${view_length}; #i += 1) ${iterations}[#i].m(${initial_mount_node}, ${initial_anchor_node});
`); `);
const dynamic = this.block.has_update_method; const dynamic = this.block.has_update_method;
@ -355,7 +371,7 @@ export default class EachBlockWrapper extends Wrapper {
${this.block.has_outros && `@group_outros();`} ${this.block.has_outros && `@group_outros();`}
${this.node.has_animation && `for (let #i = 0; #i < ${view_length}; #i += 1) ${iterations}[#i].r();`} ${this.node.has_animation && `for (let #i = 0; #i < ${view_length}; #i += 1) ${iterations}[#i].r();`}
${iterations} = @update_keyed_each(${iterations}, changed, ${get_key}, ${dynamic ? '1' : '0'}, ctx, ${this.vars.each_block_value}, ${lookup}, ${update_mount_node}, ${destroy}, ${create_each_block}, ${anchor}, ${this.vars.get_each_context}); ${iterations} = @update_keyed_each(${iterations}, changed, ${get_key}, ${dynamic ? '1' : '0'}, ctx, ${this.vars.each_block_value}, ${lookup}, ${update_mount_node}, ${destroy}, ${create_each_block}, ${update_anchor_node}, ${this.vars.get_each_context});
${this.node.has_animation && `for (let #i = 0; #i < ${view_length}; #i += 1) ${iterations}[#i].a();`} ${this.node.has_animation && `for (let #i = 0; #i < ${view_length}; #i += 1) ${iterations}[#i].a();`}
${this.block.has_outros && `@check_outros();`} ${this.block.has_outros && `@check_outros();`}
`); `);
@ -371,20 +387,30 @@ export default class EachBlockWrapper extends Wrapper {
`); `);
} }
render_unkeyed( render_unkeyed({
block,
parent_nodes,
snippet,
initial_anchor_node,
initial_mount_node,
update_anchor_node,
update_mount_node
}: {
block: Block, block: Block,
parent_node: string,
parent_nodes: string, parent_nodes: string,
snippet: string snippet: string,
) { initial_anchor_node: string,
initial_mount_node: string,
update_anchor_node: string,
update_mount_node: string
}) {
const { const {
create_each_block, create_each_block,
length, length,
iterations, iterations,
fixed_length, fixed_length,
data_length, data_length,
view_length, view_length
anchor
} = this.vars; } = this.vars;
block.builders.init.add_block(deindent` block.builders.init.add_block(deindent`
@ -395,10 +421,6 @@ export default class EachBlockWrapper extends Wrapper {
} }
`); `);
const initial_mount_node = parent_node || '#target';
const update_mount_node = this.get_update_mount_node(anchor);
const anchor_node = parent_node ? 'null' : 'anchor';
block.builders.create.add_block(deindent` block.builders.create.add_block(deindent`
for (var #i = 0; #i < ${view_length}; #i += 1) { for (var #i = 0; #i < ${view_length}; #i += 1) {
${iterations}[#i].c(); ${iterations}[#i].c();
@ -415,7 +437,7 @@ export default class EachBlockWrapper extends Wrapper {
block.builders.mount.add_block(deindent` block.builders.mount.add_block(deindent`
for (var #i = 0; #i < ${view_length}; #i += 1) { for (var #i = 0; #i < ${view_length}; #i += 1) {
${iterations}[#i].m(${initial_mount_node}, ${anchor_node}); ${iterations}[#i].m(${initial_mount_node}, ${initial_anchor_node});
} }
`); `);
@ -441,14 +463,14 @@ export default class EachBlockWrapper extends Wrapper {
${iterations}[#i] = ${create_each_block}(child_ctx); ${iterations}[#i] = ${create_each_block}(child_ctx);
${iterations}[#i].c(); ${iterations}[#i].c();
${has_transitions && `@transition_in(${this.vars.iterations}[#i], 1);`} ${has_transitions && `@transition_in(${this.vars.iterations}[#i], 1);`}
${iterations}[#i].m(${update_mount_node}, ${anchor}); ${iterations}[#i].m(${update_mount_node}, ${update_anchor_node});
} }
` `
: deindent` : deindent`
${iterations}[#i] = ${create_each_block}(child_ctx); ${iterations}[#i] = ${create_each_block}(child_ctx);
${iterations}[#i].c(); ${iterations}[#i].c();
${has_transitions && `@transition_in(${this.vars.iterations}[#i], 1);`} ${has_transitions && `@transition_in(${this.vars.iterations}[#i], 1);`}
${iterations}[#i].m(${update_mount_node}, ${anchor}); ${iterations}[#i].m(${update_mount_node}, ${update_anchor_node});
`; `;
const start = this.block.has_update_method ? '0' : `${view_length}`; const start = this.block.has_update_method ? '0' : `${view_length}`;

@ -0,0 +1,17 @@
export default {
html: `
<p>nothing</p>
<p>after</p>
`,
test({ assert, component, target }) {
component.visible = false;
assert.htmlEqual(target.innerHTML, ``);
component.visible = true;
assert.htmlEqual(target.innerHTML, `
<p>nothing</p>
<p>after</p>
`);
}
};

@ -0,0 +1,14 @@
<script>
export let visible = true;
const empty = [];
</script>
{#if visible}
{#each empty as item}
<p>{item}</p>
{:else}
<p>nothing</p>
{/each}
<p>after</p>
{/if}
Loading…
Cancel
Save