From 6ecc64f03ba70b549aa5b017c8db5bee1ff306c2 Mon Sep 17 00:00:00 2001 From: Richard Harris Date: Sat, 16 Mar 2019 12:23:27 -0400 Subject: [PATCH 1/3] failing test for #2163 --- .../component-slot-let-d/Nested.svelte | 7 +++++++ .../samples/component-slot-let-d/_config.js | 20 +++++++++++++++++++ .../samples/component-slot-let-d/main.svelte | 7 +++++++ 3 files changed, 34 insertions(+) create mode 100644 test/runtime/samples/component-slot-let-d/Nested.svelte create mode 100644 test/runtime/samples/component-slot-let-d/_config.js create mode 100644 test/runtime/samples/component-slot-let-d/main.svelte diff --git a/test/runtime/samples/component-slot-let-d/Nested.svelte b/test/runtime/samples/component-slot-let-d/Nested.svelte new file mode 100644 index 0000000000..8320e6b55d --- /dev/null +++ b/test/runtime/samples/component-slot-let-d/Nested.svelte @@ -0,0 +1,7 @@ + + +
+ +
\ No newline at end of file diff --git a/test/runtime/samples/component-slot-let-d/_config.js b/test/runtime/samples/component-slot-let-d/_config.js new file mode 100644 index 0000000000..e293ae136c --- /dev/null +++ b/test/runtime/samples/component-slot-let-d/_config.js @@ -0,0 +1,20 @@ +export default { + html: ` +
+

a

+
+ `, + + async test({ assert, target, window }) { + const div = target.querySelector('div'); + const click = new window.MouseEvent('click'); + + await div.dispatchEvent(click); + + assert.htmlEqual(target.innerHTML, ` +
+

b

+
+ `); + } +}; diff --git a/test/runtime/samples/component-slot-let-d/main.svelte b/test/runtime/samples/component-slot-let-d/main.svelte new file mode 100644 index 0000000000..09801cc700 --- /dev/null +++ b/test/runtime/samples/component-slot-let-d/main.svelte @@ -0,0 +1,7 @@ + + + +

{bar}

+
\ No newline at end of file From d9e08a80ad953bfb5225402949b51c50e98bd2bf Mon Sep 17 00:00:00 2001 From: Richard Harris Date: Sat, 16 Mar 2019 14:10:01 -0400 Subject: [PATCH 2/3] remove some update false positives --- src/compile/nodes/shared/Expression.ts | 2 +- .../wrappers/InlineComponent/index.ts | 32 ++++++++++--------- 2 files changed, 18 insertions(+), 16 deletions(-) diff --git a/src/compile/nodes/shared/Expression.ts b/src/compile/nodes/shared/Expression.ts index 0d33988fb3..eb6b12143a 100644 --- a/src/compile/nodes/shared/Expression.ts +++ b/src/compile/nodes/shared/Expression.ts @@ -150,7 +150,7 @@ export default class Expression { } component.add_reference(name); - component.warn_if_undefined(nodes[0], template_scope, true); + component.warn_if_undefined(nodes[0], template_scope); } this.skip(); diff --git a/src/compile/render-dom/wrappers/InlineComponent/index.ts b/src/compile/render-dom/wrappers/InlineComponent/index.ts index 327eee59cf..979b09d612 100644 --- a/src/compile/render-dom/wrappers/InlineComponent/index.ts +++ b/src/compile/render-dom/wrappers/InlineComponent/index.ts @@ -1,7 +1,6 @@ import Wrapper from '../shared/Wrapper'; import Renderer from '../../Renderer'; import Block from '../../Block'; -import Node from '../../../nodes/shared/Node'; import InlineComponent from '../../../nodes/InlineComponent'; import FragmentWrapper from '../Fragment'; import { quoteNameIfNecessary, quotePropIfNecessary } from '../../../../utils/quoteIfNecessary'; @@ -85,7 +84,16 @@ export default class InlineComponentWrapper extends Wrapper { }); this.fragment = new FragmentWrapper(renderer, default_slot, node.children, this, stripWhitespace, nextSibling); - block.addDependencies(default_slot.dependencies); + const dependencies = new Set(); + + // TODO is this filtering necessary? (I *think* so) + default_slot.dependencies.forEach(name => { + if (!this.node.scope.is_let(name)) { + dependencies.add(name); + } + }); + + block.addDependencies(dependencies); } block.addOutro(); @@ -160,7 +168,9 @@ export default class InlineComponentWrapper extends Wrapper { }); }); - if (!usesSpread && (this.node.attributes.filter(a => a.isDynamic).length || this.node.bindings.length || fragment_dependencies.size > 0)) { + const non_let_dependencies = Array.from(fragment_dependencies).filter(name => !this.node.scope.is_let(name)); + + if (!usesSpread && (this.node.attributes.filter(a => a.isDynamic).length || this.node.bindings.length || non_let_dependencies.length > 0)) { updates.push(`var ${name_changes} = {};`); } @@ -231,8 +241,8 @@ export default class InlineComponentWrapper extends Wrapper { } } - if (fragment_dependencies.size > 0) { - updates.push(`if (${Array.from(fragment_dependencies).map(n => `changed.${n}`).join(' || ')}) ${name_changes}.$$scope = { changed, ctx };`); + if (non_let_dependencies.length > 0) { + updates.push(`if (${non_let_dependencies.map(n => `changed.${n}`).join(' || ')}) ${name_changes}.$$scope = { changed, ctx };`); } const munged_bindings = this.node.bindings.map(binding => { @@ -482,6 +492,7 @@ export default class InlineComponentWrapper extends Wrapper { `); if (updates.length) { + console.log({ updates }); block.builders.update.addBlock(deindent` ${updates} ${name}.$set(${name_changes}); @@ -498,13 +509,4 @@ export default class InlineComponentWrapper extends Wrapper { ); } } -} - -function isComputed(node: Node) { - while (node.type === 'MemberExpression') { - if (node.computed) return true; - node = node.object; - } - - return false; -} +} \ No newline at end of file From d46e5bd8f77b4d440ea81de5d57b72c075426c0a Mon Sep 17 00:00:00 2001 From: Richard Harris Date: Sat, 16 Mar 2019 14:44:17 -0400 Subject: [PATCH 3/3] report changes correctly --- .../render-dom/wrappers/InlineComponent/index.ts | 1 - src/compile/render-dom/wrappers/Slot.ts | 2 +- .../render-dom/wrappers/shared/get_context_merger.ts | 10 +++++++++- src/internal/utils.js | 6 ++++++ 4 files changed, 16 insertions(+), 3 deletions(-) diff --git a/src/compile/render-dom/wrappers/InlineComponent/index.ts b/src/compile/render-dom/wrappers/InlineComponent/index.ts index 979b09d612..faf9d91233 100644 --- a/src/compile/render-dom/wrappers/InlineComponent/index.ts +++ b/src/compile/render-dom/wrappers/InlineComponent/index.ts @@ -492,7 +492,6 @@ export default class InlineComponentWrapper extends Wrapper { `); if (updates.length) { - console.log({ updates }); block.builders.update.addBlock(deindent` ${updates} ${name}.$set(${name_changes}); diff --git a/src/compile/render-dom/wrappers/Slot.ts b/src/compile/render-dom/wrappers/Slot.ts index 440590239d..31ca05b0df 100644 --- a/src/compile/render-dom/wrappers/Slot.ts +++ b/src/compile/render-dom/wrappers/Slot.ts @@ -142,7 +142,7 @@ export default class SlotWrapper extends Wrapper { block.builders.update.addBlock(deindent` if (${slot} && ${update_conditions}) { - ${slot}.p(@assign(@assign({}, ${get_slot_changes}(changed)), ctx.$$scope.changed), @get_slot_context(${slot_definition}, ctx, ${get_slot_context})); + ${slot}.p(@get_slot_changes(${slot_definition}, ctx, changed, ${get_slot_changes}), @get_slot_context(${slot_definition}, ctx, ${get_slot_context})); } `); diff --git a/src/compile/render-dom/wrappers/shared/get_context_merger.ts b/src/compile/render-dom/wrappers/shared/get_context_merger.ts index bbd14ec87d..fafdd28951 100644 --- a/src/compile/render-dom/wrappers/shared/get_context_merger.ts +++ b/src/compile/render-dom/wrappers/shared/get_context_merger.ts @@ -4,7 +4,15 @@ export function get_context_merger(lets: Let[]) { if (lets.length === 0) return null; const input = lets.map(l => l.value ? `${l.name}: ${l.value}` : l.name).join(', '); - const output = lets.map(l => l.names.join(', ')).join(', '); + + const names = new Set(); + lets.forEach(l => { + l.names.forEach(name => { + names.add(name); + }); + }); + + const output = Array.from(names).join(', '); return `({ ${input} }) => ({ ${output} })`; } \ No newline at end of file diff --git a/src/internal/utils.js b/src/internal/utils.js index d6b1bb6380..519d1b64d4 100644 --- a/src/internal/utils.js +++ b/src/internal/utils.js @@ -64,6 +64,12 @@ export function get_slot_context(definition, ctx, fn) { : ctx.$$scope.ctx; } +export function get_slot_changes(definition, ctx, changed, fn) { + return definition[1] + ? assign({}, assign(ctx.$$scope.changed || {}, definition[1](fn ? fn(changed) : {}))) + : ctx.$$scope.changed || {}; +} + export function exclude_internal_props(props) { const result = {}; for (const k in props) if (k[0] !== '$') result[k] = props[k];