From 7696c1fa6efaf14cca80fdbf03fafd2880e9bc3f Mon Sep 17 00:00:00 2001 From: Richard Harris Date: Tue, 25 Jun 2019 07:43:00 -0400 Subject: [PATCH 1/8] remove components without props from each block - fixes #3035 --- .../compile/render_dom/wrappers/EachBlock.ts | 2 +- .../each-block-component-no-props/Child.svelte | 1 + .../each-block-component-no-props/_config.js | 10 ++++++++++ .../each-block-component-no-props/main.svelte | 13 +++++++++++++ 4 files changed, 25 insertions(+), 1 deletion(-) create mode 100644 test/runtime/samples/each-block-component-no-props/Child.svelte create mode 100644 test/runtime/samples/each-block-component-no-props/_config.js create mode 100644 test/runtime/samples/each-block-component-no-props/main.svelte diff --git a/src/compiler/compile/render_dom/wrappers/EachBlock.ts b/src/compiler/compile/render_dom/wrappers/EachBlock.ts index 9e4f0689fa49..b57ce46b290c 100644 --- a/src/compiler/compile/render_dom/wrappers/EachBlock.ts +++ b/src/compiler/compile/render_dom/wrappers/EachBlock.ts @@ -465,7 +465,7 @@ export default class EachBlockWrapper extends Wrapper { `); remove_old_blocks = deindent` @group_outros(); - for (; #i < ${view_length}; #i += 1) ${out}(#i); + for (#i = ${this.vars.each_block_value}.${length}; #i < ${view_length}; #i += 1) ${out}(#i); @check_outros(); `; } else { diff --git a/test/runtime/samples/each-block-component-no-props/Child.svelte b/test/runtime/samples/each-block-component-no-props/Child.svelte new file mode 100644 index 000000000000..86ef4f3319bc --- /dev/null +++ b/test/runtime/samples/each-block-component-no-props/Child.svelte @@ -0,0 +1 @@ +

hello

\ No newline at end of file diff --git a/test/runtime/samples/each-block-component-no-props/_config.js b/test/runtime/samples/each-block-component-no-props/_config.js new file mode 100644 index 000000000000..6a2bc67697cb --- /dev/null +++ b/test/runtime/samples/each-block-component-no-props/_config.js @@ -0,0 +1,10 @@ +export default { + html: ` +

hello

+ `, + + async test({ assert, component, target }) { + await component.remove(); + assert.htmlEqual(target.innerHTML, ``); + } +}; diff --git a/test/runtime/samples/each-block-component-no-props/main.svelte b/test/runtime/samples/each-block-component-no-props/main.svelte new file mode 100644 index 000000000000..15139fa17bfc --- /dev/null +++ b/test/runtime/samples/each-block-component-no-props/main.svelte @@ -0,0 +1,13 @@ + + +{#each items as item} + +{/each} From 18db4100601ef6785ce2361501c30e7b37a3ff34 Mon Sep 17 00:00:00 2001 From: Richard Harris Date: Tue, 25 Jun 2019 08:05:10 -0400 Subject: [PATCH 2/8] actually this test should fail --- .../samples/each-block-component-no-props/_config.js | 6 ++++++ .../samples/each-block-component-no-props/main.svelte | 4 ++++ 2 files changed, 10 insertions(+) diff --git a/test/runtime/samples/each-block-component-no-props/_config.js b/test/runtime/samples/each-block-component-no-props/_config.js index 6a2bc67697cb..e8344496ca6f 100644 --- a/test/runtime/samples/each-block-component-no-props/_config.js +++ b/test/runtime/samples/each-block-component-no-props/_config.js @@ -6,5 +6,11 @@ export default { async test({ assert, component, target }) { await component.remove(); assert.htmlEqual(target.innerHTML, ``); + + await component.add(); + assert.htmlEqual(target.innerHTML, `

hello

`); + + await component.remove(); + assert.htmlEqual(target.innerHTML, ``); } }; diff --git a/test/runtime/samples/each-block-component-no-props/main.svelte b/test/runtime/samples/each-block-component-no-props/main.svelte index 15139fa17bfc..01299fe31418 100644 --- a/test/runtime/samples/each-block-component-no-props/main.svelte +++ b/test/runtime/samples/each-block-component-no-props/main.svelte @@ -3,6 +3,10 @@ let items = [1]; + export function add() { + items = [1]; + } + export function remove() { items = []; } From f9fbefe5ebf63af92bea608b13fc745916b886d3 Mon Sep 17 00:00:00 2001 From: Richard Harris Date: Tue, 25 Jun 2019 08:43:09 -0400 Subject: [PATCH 3/8] fix #3035 for real --- .../compile/render_dom/wrappers/EachBlock.ts | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/src/compiler/compile/render_dom/wrappers/EachBlock.ts b/src/compiler/compile/render_dom/wrappers/EachBlock.ts index b57ce46b290c..6f592d386977 100644 --- a/src/compiler/compile/render_dom/wrappers/EachBlock.ts +++ b/src/compiler/compile/render_dom/wrappers/EachBlock.ts @@ -445,13 +445,18 @@ export default class EachBlockWrapper extends Wrapper { } ` : deindent` - ${iterations}[#i] = ${create_each_block}(child_ctx); - ${iterations}[#i].c(); - ${has_transitions && `@transition_in(${this.vars.iterations}[#i], 1);`} - ${iterations}[#i].m(${update_mount_node}, ${anchor}); + if (${iterations}[#i]) { + ${has_transitions && `@transition_in(${this.vars.iterations}[#i], 1);`} + } else { + ${iterations}[#i] = ${create_each_block}(child_ctx); + ${iterations}[#i].c(); + ${has_transitions && `@transition_in(${this.vars.iterations}[#i], 1);`} + ${iterations}[#i].m(${update_mount_node}, ${anchor}); + } + `; - const start = this.block.has_update_method ? '0' : `${view_length}`; + const start = this.block.has_update_method ? '0' : `old_length`; let remove_old_blocks; @@ -470,7 +475,7 @@ export default class EachBlockWrapper extends Wrapper { `; } else { remove_old_blocks = deindent` - for (${this.block.has_update_method ? `` : `#i = ${this.vars.each_block_value}.${length}`}; #i < ${view_length}; #i += 1) { + for (${this.block.has_update_method ? `` : `#i = ${this.vars.each_block_value}.${length}`}; #i < ${this.block.has_update_method ? view_length : 'old_length'}; #i += 1) { ${iterations}[#i].d(1); } ${!fixed_length && `${view_length} = ${this.vars.each_block_value}.${length};`} @@ -478,6 +483,7 @@ export default class EachBlockWrapper extends Wrapper { } const update = deindent` + ${!this.block.has_update_method && `const old_length = ${this.vars.each_block_value}.length;`} ${this.vars.each_block_value} = ${snippet}; for (var #i = ${start}; #i < ${this.vars.each_block_value}.${length}; #i += 1) { From bdf01d632cd38ce810d86238790c93244a1db53f Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Tue, 25 Jun 2019 10:38:04 -0400 Subject: [PATCH 4/8] add a few more known globals --- src/compiler/utils/names.ts | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/compiler/utils/names.ts b/src/compiler/utils/names.ts index 9805c92b917b..c5a67a651be7 100644 --- a/src/compiler/utils/names.ts +++ b/src/compiler/utils/names.ts @@ -14,7 +14,9 @@ export const globals = new Set([ 'encodeURI', 'encodeURIComponent', 'Error', + 'EvalError', 'Infinity', + 'InternalError', 'Intl', 'isFinite', 'isNaN', @@ -29,11 +31,16 @@ export const globals = new Set([ 'process', 'Promise', 'prompt', + 'RangeError', + 'ReferenceError', 'RegExp', 'Set', 'String', + 'SyntaxError', + 'TypeError', 'undefined', - 'window', + 'URIError', + 'window' ]); export const reserved = new Set([ From b9b8575f55037c66f651575d893c2f84e341bc73 Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Tue, 25 Jun 2019 10:41:42 -0400 Subject: [PATCH 5/8] prevent empty if block --- .../compile/render_dom/wrappers/EachBlock.ts | 29 ++++++++++++------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/src/compiler/compile/render_dom/wrappers/EachBlock.ts b/src/compiler/compile/render_dom/wrappers/EachBlock.ts index 6f592d386977..c2f6c50249b1 100644 --- a/src/compiler/compile/render_dom/wrappers/EachBlock.ts +++ b/src/compiler/compile/render_dom/wrappers/EachBlock.ts @@ -444,17 +444,24 @@ export default class EachBlockWrapper extends Wrapper { ${iterations}[#i].m(${update_mount_node}, ${anchor}); } ` - : deindent` - if (${iterations}[#i]) { - ${has_transitions && `@transition_in(${this.vars.iterations}[#i], 1);`} - } else { - ${iterations}[#i] = ${create_each_block}(child_ctx); - ${iterations}[#i].c(); - ${has_transitions && `@transition_in(${this.vars.iterations}[#i], 1);`} - ${iterations}[#i].m(${update_mount_node}, ${anchor}); - } - - `; + : has_transitions + ? deindent` + if (${iterations}[#i]) { + @transition_in(${this.vars.iterations}[#i], 1); + } else { + ${iterations}[#i] = ${create_each_block}(child_ctx); + ${iterations}[#i].c(); + @transition_in(${this.vars.iterations}[#i], 1); + ${iterations}[#i].m(${update_mount_node}, ${anchor}); + } + ` + : deindent` + if (!${iterations}[#i]) { + ${iterations}[#i] = ${create_each_block}(child_ctx); + ${iterations}[#i].c(); + ${iterations}[#i].m(${update_mount_node}, ${anchor}); + } + `; const start = this.block.has_update_method ? '0' : `old_length`; From 177680fa2c3ca706e6ae5ba3aca2e90a75cbf33a Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Tue, 25 Jun 2019 10:49:03 -0400 Subject: [PATCH 6/8] doh --- src/compiler/compile/render_dom/wrappers/EachBlock.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/compiler/compile/render_dom/wrappers/EachBlock.ts b/src/compiler/compile/render_dom/wrappers/EachBlock.ts index c2f6c50249b1..06d8d5593f66 100644 --- a/src/compiler/compile/render_dom/wrappers/EachBlock.ts +++ b/src/compiler/compile/render_dom/wrappers/EachBlock.ts @@ -463,7 +463,7 @@ export default class EachBlockWrapper extends Wrapper { } `; - const start = this.block.has_update_method ? '0' : `old_length`; + const start = this.block.has_update_method ? '0' : `#old_length`; let remove_old_blocks; @@ -482,7 +482,7 @@ export default class EachBlockWrapper extends Wrapper { `; } else { remove_old_blocks = deindent` - for (${this.block.has_update_method ? `` : `#i = ${this.vars.each_block_value}.${length}`}; #i < ${this.block.has_update_method ? view_length : 'old_length'}; #i += 1) { + for (${this.block.has_update_method ? `` : `#i = ${this.vars.each_block_value}.${length}`}; #i < ${this.block.has_update_method ? view_length : '#old_length'}; #i += 1) { ${iterations}[#i].d(1); } ${!fixed_length && `${view_length} = ${this.vars.each_block_value}.${length};`} @@ -490,7 +490,7 @@ export default class EachBlockWrapper extends Wrapper { } const update = deindent` - ${!this.block.has_update_method && `const old_length = ${this.vars.each_block_value}.length;`} + ${!this.block.has_update_method && `const #old_length = ${this.vars.each_block_value}.length;`} ${this.vars.each_block_value} = ${snippet}; for (var #i = ${start}; #i < ${this.vars.each_block_value}.${length}; #i += 1) { From f2044c4e1c4b74d480166e274e79c8654e0b28bb Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Tue, 25 Jun 2019 11:09:55 -0400 Subject: [PATCH 7/8] check for existence of switch instance before introing - fixes #3054 --- .../compile/render_dom/wrappers/InlineComponent/index.ts | 2 +- .../samples/dynamic-component-nulled-out-intro/_config.js | 5 +++++ .../samples/dynamic-component-nulled-out-intro/main.svelte | 7 +++++++ 3 files changed, 13 insertions(+), 1 deletion(-) create mode 100644 test/runtime/samples/dynamic-component-nulled-out-intro/_config.js create mode 100644 test/runtime/samples/dynamic-component-nulled-out-intro/main.svelte diff --git a/src/compiler/compile/render_dom/wrappers/InlineComponent/index.ts b/src/compiler/compile/render_dom/wrappers/InlineComponent/index.ts index 46b3df4c31fd..6045daaf36dd 100644 --- a/src/compiler/compile/render_dom/wrappers/InlineComponent/index.ts +++ b/src/compiler/compile/render_dom/wrappers/InlineComponent/index.ts @@ -447,7 +447,7 @@ export default class InlineComponentWrapper extends Wrapper { `); block.builders.intro.add_block(deindent` - @transition_in(${name}.$$.fragment, #local); + if (${name}) @transition_in(${name}.$$.fragment, #local); `); if (updates.length) { diff --git a/test/runtime/samples/dynamic-component-nulled-out-intro/_config.js b/test/runtime/samples/dynamic-component-nulled-out-intro/_config.js new file mode 100644 index 000000000000..9759ada538d2 --- /dev/null +++ b/test/runtime/samples/dynamic-component-nulled-out-intro/_config.js @@ -0,0 +1,5 @@ +export default { + test({ component }) { + component.visible = true; + } +}; \ No newline at end of file diff --git a/test/runtime/samples/dynamic-component-nulled-out-intro/main.svelte b/test/runtime/samples/dynamic-component-nulled-out-intro/main.svelte new file mode 100644 index 000000000000..eac72cf694a6 --- /dev/null +++ b/test/runtime/samples/dynamic-component-nulled-out-intro/main.svelte @@ -0,0 +1,7 @@ + + +{#if visible} + +{/if} \ No newline at end of file From d10d491579b4d06c1b57c6726d0c75da873e027d Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Tue, 25 Jun 2019 11:16:47 -0400 Subject: [PATCH 8/8] sanitize names of automatically-bubbled events - fixes #2923 --- src/compiler/compile/nodes/EventHandler.ts | 3 ++- .../_config.js | 18 ++++++++++++++++++ .../main.svelte | 1 + 3 files changed, 21 insertions(+), 1 deletion(-) create mode 100644 test/runtime/samples/event-handler-shorthand-sanitized/_config.js create mode 100644 test/runtime/samples/event-handler-shorthand-sanitized/main.svelte diff --git a/src/compiler/compile/nodes/EventHandler.ts b/src/compiler/compile/nodes/EventHandler.ts index 20e662a22bea..f2c48c316999 100644 --- a/src/compiler/compile/nodes/EventHandler.ts +++ b/src/compiler/compile/nodes/EventHandler.ts @@ -3,6 +3,7 @@ import Expression from './shared/Expression'; import Component from '../Component'; import deindent from '../utils/deindent'; import Block from '../render_dom/Block'; +import { sanitize } from '../../utils/names'; export default class EventHandler extends Node { type: 'EventHandler'; @@ -41,7 +42,7 @@ export default class EventHandler extends Node { } } } else { - const name = component.get_unique_name(`${this.name}_handler`); + const name = component.get_unique_name(`${sanitize(this.name)}_handler`); component.add_var({ name, diff --git a/test/runtime/samples/event-handler-shorthand-sanitized/_config.js b/test/runtime/samples/event-handler-shorthand-sanitized/_config.js new file mode 100644 index 000000000000..030e27ad1a12 --- /dev/null +++ b/test/runtime/samples/event-handler-shorthand-sanitized/_config.js @@ -0,0 +1,18 @@ +export default { + html: ` + + `, + + test({ assert, component, target, window }) { + const button = target.querySelector('button'); + const event = new window.Event('click-now'); + + let clicked; + component.$on('click-now', () => { + clicked = true; + }); + + button.dispatchEvent(event); + assert.ok(clicked); + } +}; diff --git a/test/runtime/samples/event-handler-shorthand-sanitized/main.svelte b/test/runtime/samples/event-handler-shorthand-sanitized/main.svelte new file mode 100644 index 000000000000..05de1316efae --- /dev/null +++ b/test/runtime/samples/event-handler-shorthand-sanitized/main.svelte @@ -0,0 +1 @@ + \ No newline at end of file