fix: add top level snippets to instance scope

fixes #9460
pull/9467/head
Simon Holthausen 3 years ago
parent 640dd48705
commit 67c3f696a0

@ -0,0 +1,5 @@
---
'svelte': patch
---
fix: add top level snippets to instance scope

@ -273,15 +273,6 @@ export function create_scopes(ast, root, allow_reactive_declarations, parent) {
next({ scope });
};
/**
* @type {import('zimmerframe').Visitor<import('#compiler').SvelteNode, State, import('#compiler').SvelteNode>}
*/
const CreateBlock = (node, { state, next }) => {
const scope = state.scope.child();
scopes.set(node, scope);
next({ scope });
};
/**
* @param {import('#compiler').ElementLike} node
* @param {Scope} parent
@ -566,18 +557,24 @@ export function create_scopes(ast, root, allow_reactive_declarations, parent) {
},
SnippetBlock(node, context) {
state.scope.declare(node.expression, 'normal', 'function', node.expression);
// Special-case for root-level snippets: they become part of the instance scope
const is_top_level = !context.path.at(-2);
let scope = state.scope;
if (is_top_level) {
scope = /** @type {Scope} */ (parent);
}
scope.declare(node.expression, 'normal', 'function', node.expression);
const scope = state.scope.child();
scopes.set(node, scope);
const child_scope = state.scope.child();
scopes.set(node, child_scope);
if (node.context) {
for (const id of extract_identifiers(node.context)) {
scope.declare(id, 'each', 'let');
child_scope.declare(id, 'each', 'let');
}
}
context.next({ scope });
context.next({ scope: child_scope });
},
Fragment: (node, context) => {
@ -586,9 +583,6 @@ export function create_scopes(ast, root, allow_reactive_declarations, parent) {
context.next({ scope });
},
// TODO this will be unnecessary when we switch to fragments
IfBlock: CreateBlock,
BindDirective(node, context) {
updates.push([
context.state.scope,

@ -0,0 +1,31 @@
// input.svelte (Svelte VERSION)
// Note: compiler output will change before 5.0 is released!
import "svelte/internal/disclose-version";
import * as $ from "svelte/internal";
function log(_, snippet) {
console.log(snippet);
}
var frag_1 = $.template(`Hello`, true);
var frag = $.template(`<button>log snippet</button>`);
export default function Input($$anchor, $$props) {
$.push($$props, false);
/* Init */
var button = $.open($$anchor, true, frag);
function snippet($$anchor) {
/* Init */
var fragment = $.open_frag($$anchor, true, frag_1);
$.close_frag($$anchor, fragment);
}
button.__click = [log, snippet];
$.close($$anchor, button);
$.pop();
}
$.delegate(["click"]);

@ -0,0 +1,22 @@
// input.svelte (Svelte VERSION)
// Note: compiler output will change before 5.0 is released!
import * as $ from "svelte/internal/server";
export default function Input($$payload, $$props) {
$.push(false);
function log() {
console.log(snippet);
}
function snippet($$payload) {
const anchor = $.create_anchor($$payload);
$$payload.out += anchor;
$$payload.out += `Hello`;
$$payload.out += anchor;
}
$$payload.out += `<button>log snippet</button>`;
$.pop();
}

@ -0,0 +1,11 @@
<script>
function log() {
console.log(snippet)
}
</script>
{#snippet snippet()}Hello{/snippet}
<button on:click={log}>
log snippet
</button>
Loading…
Cancel
Save