From 639c2fb9ea51e23c959e8c2127f5ede14740fffb Mon Sep 17 00:00:00 2001 From: tanhauhau Date: Thu, 14 Apr 2022 17:42:02 +0800 Subject: [PATCH] support else for each block too fix lint errors --- .../compile/render_dom/wrappers/EachBlock.ts | 21 ++++++++++++--- .../compile/render_ssr/handlers/EachBlock.ts | 4 ++- .../samples/const-tag-each-else/_config.js | 26 +++++++++++++++++++ .../samples/const-tag-each-else/main.svelte | 22 ++++++++++++++++ 4 files changed, 68 insertions(+), 5 deletions(-) create mode 100644 test/runtime/samples/const-tag-each-else/_config.js create mode 100644 test/runtime/samples/const-tag-each-else/main.svelte diff --git a/src/compiler/compile/render_dom/wrappers/EachBlock.ts b/src/compiler/compile/render_dom/wrappers/EachBlock.ts index b77b2472df..db7929e51b 100644 --- a/src/compiler/compile/render_dom/wrappers/EachBlock.ts +++ b/src/compiler/compile/render_dom/wrappers/EachBlock.ts @@ -27,6 +27,7 @@ export class ElseBlockWrapper extends Wrapper { next_sibling: Wrapper ) { super(renderer, block, parent, node); + add_const_tags_context(renderer, this.node.const_tags); this.block = block.child({ comment: create_debugging_comment(node, this.renderer.component), @@ -257,6 +258,18 @@ export default class EachBlockWrapper extends Wrapper { } if (this.else) { + let else_ctx = x`#ctx`; + if (this.else.node.const_tags.length > 0) { + const get_ctx_name = this.renderer.component.get_unique_name('get_else_ctx'); + this.renderer.blocks.push(b` + function ${get_ctx_name}(#ctx) { + const child_ctx = #ctx.slice(); + ${add_const_tags(block, this.else.node.const_tags, 'child_ctx')} + return child_ctx; + } + `); + else_ctx = x`${get_ctx_name}(#ctx)`; + } const each_block_else = component.get_unique_name(`${this.var.name}_else`); block.chunks.init.push(b`let ${each_block_else} = null;`); @@ -264,7 +277,7 @@ export default class EachBlockWrapper extends Wrapper { // TODO neaten this up... will end up with an empty line in the block block.chunks.init.push(b` if (!${this.vars.data_length}) { - ${each_block_else} = ${this.else.block.name}(#ctx); + ${each_block_else} = ${this.else.block.name}(${else_ctx}); } `); @@ -304,9 +317,9 @@ export default class EachBlockWrapper extends Wrapper { if (this.else.block.has_update_method) { this.updates.push(b` if (!${this.vars.data_length} && ${each_block_else}) { - ${each_block_else}.p(#ctx, #dirty); + ${each_block_else}.p(${else_ctx}, #dirty); } else if (!${this.vars.data_length}) { - ${each_block_else} = ${this.else.block.name}(#ctx); + ${each_block_else} = ${this.else.block.name}(${else_ctx}); ${each_block_else}.c(); ${has_transitions && b`@transition_in(${each_block_else}, 1);`} ${each_block_else}.m(${update_mount_node}, ${update_anchor_node}); @@ -321,7 +334,7 @@ export default class EachBlockWrapper extends Wrapper { ${destroy_block_else}; } } else if (!${each_block_else}) { - ${each_block_else} = ${this.else.block.name}(#ctx); + ${each_block_else} = ${this.else.block.name}(${else_ctx}); ${each_block_else}.c(); ${has_transitions && b`@transition_in(${each_block_else}, 1);`} ${each_block_else}.m(${update_mount_node}, ${update_anchor_node}); diff --git a/src/compiler/compile/render_ssr/handlers/EachBlock.ts b/src/compiler/compile/render_ssr/handlers/EachBlock.ts index 008c023e11..2b9149ffef 100644 --- a/src/compiler/compile/render_ssr/handlers/EachBlock.ts +++ b/src/compiler/compile/render_ssr/handlers/EachBlock.ts @@ -2,6 +2,7 @@ import Renderer, { RenderOptions } from '../Renderer'; import EachBlock from '../../nodes/EachBlock'; import { x } from 'code-red'; import { get_const_tags } from './shared/get_const_tags'; +import { Node } from 'estree'; export default function(node: EachBlock, renderer: Renderer, options: RenderOptions) { const args = [node.context_node]; @@ -16,7 +17,8 @@ export default function(node: EachBlock, renderer: Renderer, options: RenderOpti if (node.else) { renderer.push(); renderer.render(node.else.children, options); - const alternate = renderer.pop(); + let alternate: Node = renderer.pop(); + if (node.else.const_tags.length > 0) alternate = x`(() => { ${get_const_tags(node.else.const_tags)}; return ${alternate} })()`; renderer.add_expression(x`${node.expression.node}.length ? ${consequent} : ${alternate}`); } else { diff --git a/test/runtime/samples/const-tag-each-else/_config.js b/test/runtime/samples/const-tag-each-else/_config.js new file mode 100644 index 0000000000..d95be09ccc --- /dev/null +++ b/test/runtime/samples/const-tag-each-else/_config.js @@ -0,0 +1,26 @@ +export default { + html: ` +
12 120 70, 30+4=34
+
35 350 120, 50+7=57
+
48 480 140, 60+8=68
+ `, + async test({ component, target, assert }) { + component.boxes = []; + assert.htmlEqual(target.innerHTML, ` +
10 * 2 = 20
+ `); + + component.constant = 35; + assert.htmlEqual(target.innerHTML, ` +
35 * 2 = 70
+ `); + + component.boxes = [ + {width: 3, height: 4} + ]; + + assert.htmlEqual(target.innerHTML, ` +
12 420 245, 105+4=109
+ `); + } +}; diff --git a/test/runtime/samples/const-tag-each-else/main.svelte b/test/runtime/samples/const-tag-each-else/main.svelte new file mode 100644 index 0000000000..7701a579cf --- /dev/null +++ b/test/runtime/samples/const-tag-each-else/main.svelte @@ -0,0 +1,22 @@ + + +{#each boxes as box} + {@const {area, volume} = calculate(box.width, box.height, constant)} + {@const perimeter = (box.width + box.height) * constant} + {@const [width, height, sum] = [box.width * constant, box.height, box.width * constant + box.height]} +
{area} {volume} {perimeter}, {width}+{height}={sum}
+{:else} + {@const double = constant + constant} +
{constant} * 2 = {double}
+{/each} \ No newline at end of file