diff --git a/src/compile/nodes/shared/Expression.ts b/src/compile/nodes/shared/Expression.ts index 818066f21a..a4281eac64 100644 --- a/src/compile/nodes/shared/Expression.ts +++ b/src/compile/nodes/shared/Expression.ts @@ -122,8 +122,16 @@ export default class Expression { const { name, nodes } = flattenReference(node); if (scope.has(name)) return; + if (globalWhitelist.has(name) && !component.var_lookup.has(name)) return; + if (name[0] === '$' && template_scope.names.has(name.slice(1))) { + component.error(node, { + code: `contextual-store`, + message: `Stores must be declared at the top level of the component (this may change in a future version of Svelte)` + }); + } + if (template_scope.is_let(name)) { if (!function_expression) { dependencies.add(name); diff --git a/test/runtime/samples/store-contextual/_config.js b/test/runtime/samples/store-contextual/_config.js new file mode 100644 index 0000000000..c759ede650 --- /dev/null +++ b/test/runtime/samples/store-contextual/_config.js @@ -0,0 +1,76 @@ +import { writable } from '../../../../store.js'; + +const todos = [ + writable({ done: false, text: 'write docs' }), + writable({ done: false, text: 'implement contextual stores' }), + writable({ done: false, text: 'go outside' }) +]; + +export default { + error: `Stores must be declared at the top level of the component (this may change in a future version of Svelte)`, + + props: { + todos + }, + + html: ` + + + + + + `, + + async test({ assert, component, target, window }) { + const inputs = target.querySelectorAll('input'); + const change = new window.MouseEvent('change'); + + inputs[1].checked = true; + await inputs[1].dispatchEvent(change); + + assert.htmlEqual(target.innerHTML, ` + + + + + + `); + + await todos[0].update(todo => ({ done: !todo.done, text: todo.text })); + + assert.htmlEqual(target.innerHTML, ` + + + + + + `); + } +}; \ No newline at end of file diff --git a/test/runtime/samples/store-contextual/main.svelte b/test/runtime/samples/store-contextual/main.svelte new file mode 100644 index 0000000000..f8403eded4 --- /dev/null +++ b/test/runtime/samples/store-contextual/main.svelte @@ -0,0 +1,6 @@ +{#each todos as todo} + +{/each} \ No newline at end of file