ensure var names in binding callbacks are unique — fixes #495

pull/499/head
Rich-Harris 8 years ago
parent c40966fdc7
commit b0095bda9d

@ -3,7 +3,7 @@ import flattenReference from '../../../../utils/flattenReference.js';
import getSetter from '../shared/binding/getSetter.js'; import getSetter from '../shared/binding/getSetter.js';
export default function visitBinding ( generator, block, state, node, attribute, local ) { export default function visitBinding ( generator, block, state, node, attribute, local ) {
const { name, keypath } = flattenReference( attribute.value ); const { name } = flattenReference( attribute.value );
const { snippet, contexts, dependencies } = block.contextualise( attribute.value ); const { snippet, contexts, dependencies } = block.contextualise( attribute.value );
if ( dependencies.length > 1 ) throw new Error( 'An unexpected situation arose. Please raise an issue at https://github.com/sveltejs/svelte/issues — thanks!' ); if ( dependencies.length > 1 ) throw new Error( 'An unexpected situation arose. Please raise an issue at https://github.com/sveltejs/svelte/issues — thanks!' );
@ -35,7 +35,7 @@ export default function visitBinding ( generator, block, state, node, attribute,
prop prop
}); });
const setter = getSetter({ block, name, keypath, context: '_context', attribute, dependencies, value: 'value' }); const setter = getSetter({ block, name, context: '_context', attribute, dependencies, value: 'value' });
generator.hasComplexBindings = true; generator.hasComplexBindings = true;

@ -20,7 +20,7 @@ export default function visitBinding ( generator, block, state, node, attribute
const bindingGroup = attribute.name === 'group' ? getBindingGroup( generator, keypath ) : null; const bindingGroup = attribute.name === 'group' ? getBindingGroup( generator, keypath ) : null;
const value = getBindingValue( generator, block, state, node, attribute, isMultipleSelect, bindingGroup, type ); const value = getBindingValue( generator, block, state, node, attribute, isMultipleSelect, bindingGroup, type );
let setter = getSetter({ block, name, keypath, context: '_svelte', attribute, dependencies, value }); let setter = getSetter({ block, name, context: '_svelte', attribute, dependencies, value });
let updateElement = `${state.parentNode}.${attribute.name} = ${snippet};`; let updateElement = `${state.parentNode}.${attribute.name} = ${snippet};`;
const lock = block.getUniqueName( `${state.parentNode}_${attribute.name}_updating` ); const lock = block.getUniqueName( `${state.parentNode}_${attribute.name}_updating` );
let updateCondition = `!${lock}`; let updateCondition = `!${lock}`;

@ -1,9 +1,10 @@
import deindent from '../../../../../utils/deindent.js'; import deindent from '../../../../../utils/deindent.js';
export default function getSetter ({ block, name, keypath, context, attribute, dependencies, value }) { export default function getSetter ({ block, name, context, attribute, dependencies, value }) {
const tail = attribute.value.type === 'MemberExpression' ? getTailSnippet( attribute.value ) : '';
if ( block.contexts.has( name ) ) { if ( block.contexts.has( name ) ) {
const prop = dependencies[0]; const prop = dependencies[0];
const tail = attribute.value.type === 'MemberExpression' ? getTailSnippet( attribute.value ) : '';
return deindent` return deindent`
var list = this.${context}.${block.listNames.get( name )}; var list = this.${context}.${block.listNames.get( name )};
@ -15,10 +16,12 @@ export default function getSetter ({ block, name, keypath, context, attribute, d
} }
if ( attribute.value.type === 'MemberExpression' ) { if ( attribute.value.type === 'MemberExpression' ) {
const alias = block.alias( name );
return deindent` return deindent`
var ${name} = ${block.component}.get( '${name}' ); var ${alias} = ${block.component}.get( '${name}' );
${keypath} = ${value}; ${alias}${tail} = ${value};
${block.component}._set({ ${name}: ${name} }); ${block.component}._set({ ${name}: ${alias} });
`; `;
} }

@ -1,6 +1,4 @@
export default { export default {
solo: true,
data: { data: {
component: { component: {
name: 'world' name: 'world'
@ -21,14 +19,15 @@ export default {
input.value = 'everybody'; input.value = 'everybody';
input.dispatchEvent( event ); input.dispatchEvent( event );
assert.equal( target.innerHTML, ` assert.equal( input.value, 'everybody' );
assert.htmlEqual( target.innerHTML, `
<h1>Hello everybody!</h1> <h1>Hello everybody!</h1>
<input> <input>
` ); ` );
component.set({ name: 'goodbye' }); component.set({ component: { name: 'goodbye' } });
assert.equal( input.value, 'goodbye' ); assert.equal( input.value, 'goodbye' );
assert.equal( target.innerHTML, ` assert.htmlEqual( target.innerHTML, `
<h1>Hello goodbye!</h1> <h1>Hello goodbye!</h1>
<input> <input>
` ); ` );

Loading…
Cancel
Save