fix: allow member access on directives (#9462)

fixes #9445
pull/9465/head
Paolo Ricciuti 2 years ago committed by GitHub
parent 9eb969ddd4
commit 6f3dc04c82
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -0,0 +1,5 @@
---
"svelte": patch
---
fix: allow member access on directives

@ -74,6 +74,22 @@ function serialize_style_directives(style_directives, element_id, context, is_at
}
}
/**
* goes from nested.access to nested['access']
* @param {string} expression
*/
function member_expression_id_to_literal(expression) {
// this allow for accessing members of an object
const splitted_expression = expression.split('.');
let new_expression = splitted_expression.shift() ?? '';
for (let new_piece of splitted_expression) {
new_expression += `['${new_piece}']`;
}
return new_expression;
}
/**
* Serializes each class directive into something like `$.class_toogle(element, class_name, value)`
* and adds it either to init or update, depending on whether or not the value or the attributes are dynamic.
@ -1676,7 +1692,16 @@ export const template_visitors = {
? b.literal(null)
: b.thunk(/** @type {import('estree').Expression} */ (visit(node.expression)));
state.init.push(b.stmt(b.call('$.animate', state.node, b.id(node.name), expression)));
state.init.push(
b.stmt(
b.call(
'$.animate',
state.node,
b.id(member_expression_id_to_literal(node.name)),
expression
)
)
);
},
ClassDirective(node, { state, next }) {
error(node, 'INTERNAL', 'Node should have been handled elsewhere');
@ -1696,7 +1721,7 @@ export const template_visitors = {
b.call(
type,
state.node,
b.id(node.name),
b.id(member_expression_id_to_literal(node.name)),
expression,
node.modifiers.includes('global') ? b.true : b.false
)
@ -2417,7 +2442,13 @@ export const template_visitors = {
/** @type {import('estree').Expression[]} */
const args = [
state.node,
b.arrow(params, b.call(serialize_get_binding(b.id(node.name), state), ...params))
b.arrow(
params,
b.call(
serialize_get_binding(b.id(member_expression_id_to_literal(node.name)), state),
...params
)
)
];
if (node.expression) {

@ -0,0 +1,5 @@
import { test } from '../../test';
export default test({
skip_if_ssr: true
});

@ -0,0 +1,108 @@
// index.svelte (Svelte VERSION)
// Note: compiler output will change before 5.0 is released!
import "svelte/internal/disclose-version";
import * as $ from "svelte/internal";
var frag = $.template(`<div></div> <div></div> <div></div> <div></div> <div></div> <div></div> <div></div> <div></div> <div></div> <div></div> <div></div> <div></div> <div></div> <div></div> <div></div> <div></div> <div></div> <div></div> <div></div> <div></div> <div></div> <div></div> <div></div> <div></div> <div></div>`, true);
export default function Directives_with_member_access($$anchor, $$props) {
$.push($$props, false);
const one = () => {};
const nested = { one, "with-string": one };
const evenmore = { nested };
/* Init */
var fragment = $.open_frag($$anchor, true, frag);
var div = $.child_frag(fragment);
var div_1 = $.sibling($.sibling(div));
var div_2 = $.sibling($.sibling(div_1));
var div_3 = $.sibling($.sibling(div_2));
$.transition(div_3, one, null, false);
var div_4 = $.sibling($.sibling(div_3));
$.transition(div_4, nested['one'], null, false);
var div_5 = $.sibling($.sibling(div_4));
$.transition(div_5, evenmore['nested']['one'], null, false);
var div_6 = $.sibling($.sibling(div_5));
$.animate(div_6, one, null);
var div_7 = $.sibling($.sibling(div_6));
$.animate(div_7, nested['one'], null);
var div_8 = $.sibling($.sibling(div_7));
$.animate(div_8, evenmore['nested']['one'], null);
var div_9 = $.sibling($.sibling(div_8));
$.in(div_9, one, null, false);
var div_10 = $.sibling($.sibling(div_9));
$.in(div_10, nested['one'], null, false);
var div_11 = $.sibling($.sibling(div_10));
$.in(div_11, evenmore['nested']['one'], null, false);
var div_12 = $.sibling($.sibling(div_11));
$.out(div_12, one, null, false);
var div_13 = $.sibling($.sibling(div_12));
$.out(div_13, nested['one'], null, false);
var div_14 = $.sibling($.sibling(div_13));
$.out(div_14, evenmore['nested']['one'], null, false);
var div_15 = $.sibling($.sibling(div_14));
var div_16 = $.sibling($.sibling(div_15));
var div_17 = $.sibling($.sibling(div_16));
$.transition(div_17, nested['with-string'], null, false);
var div_18 = $.sibling($.sibling(div_17));
$.transition(div_18, evenmore['nested']['with-string'], null, false);
var div_19 = $.sibling($.sibling(div_18));
$.animate(div_19, nested['with-string'], null);
var div_20 = $.sibling($.sibling(div_19));
$.animate(div_20, evenmore['nested']['with-string'], null);
var div_21 = $.sibling($.sibling(div_20));
$.in(div_21, nested['with-string'], null, false);
var div_22 = $.sibling($.sibling(div_21));
$.in(div_22, evenmore['nested']['with-string'], null, false);
var div_23 = $.sibling($.sibling(div_22));
$.out(div_23, nested['with-string'], null, false);
var div_24 = $.sibling($.sibling(div_23));
$.out(div_24, evenmore['nested']['with-string'], null, false);
$.action(div, $$node => one($$node));
$.action(div_1, $$node => nested['one']($$node));
$.action(div_2, $$node => evenmore['nested']['one']($$node));
$.action(div_15, $$node => nested['with-string']($$node));
$.action(div_16, $$node => evenmore['nested']['with-string']($$node));
$.close_frag($$anchor, fragment);
$.pop();
}

@ -0,0 +1,40 @@
<script>
const one = ()=>{};
const nested = {one, "with-string": one};
const evenmore = {nested};
</script>
<div use:one />
<div use:nested.one />
<div use:evenmore.nested.one />
<div transition:one />
<div transition:nested.one />
<div transition:evenmore.nested.one />
<div animate:one />
<div animate:nested.one />
<div animate:evenmore.nested.one />
<div in:one />
<div in:nested.one />
<div in:evenmore.nested.one />
<div out:one />
<div out:nested.one />
<div out:evenmore.nested.one />
<div use:nested.with-string />
<div use:evenmore.nested.with-string />
<div transition:nested.with-string />
<div transition:evenmore.nested.with-string />
<div animate:nested.with-string />
<div animate:evenmore.nested.with-string />
<div in:nested.with-string />
<div in:evenmore.nested.with-string />
<div out:nested.with-string />
<div out:evenmore.nested.with-string />

@ -7,11 +7,14 @@ import { VERSION } from 'svelte/compiler';
interface SnapshotTest extends BaseTest {
compileOptions?: Partial<import('#compiler').CompileOptions>;
skip_if_ssr?: boolean;
}
const { test, run } = suite<SnapshotTest>(async (config, cwd) => {
compile_directory(cwd, 'client', config.compileOptions);
compile_directory(cwd, 'server', config.compileOptions);
if (!config.skip_if_ssr) {
compile_directory(cwd, 'server', config.compileOptions);
}
// run `UPDATE_SNAPSHOTS=true pnpm test snapshot` to update snapshot tests
if (process.env.UPDATE_SNAPSHOTS) {

Loading…
Cancel
Save