Skip to content

Commit 2194de9

Browse files
authored
Merge pull request #591 from sveltejs/gh-590
On `<select>`, don't try generating prop code until visiting attributes
2 parents 7c2fd8e + a3860f2 commit 2194de9

File tree

3 files changed

+68
-34
lines changed

3 files changed

+68
-34
lines changed

src/generators/dom/visitors/Element/Element.js

+34-34
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ export default function visitElement ( generator, block, state, node ) {
4646
block.builders.create.addLine( `${generator.helper( 'setAttribute' )}( ${name}, '${generator.cssId}', '' );` );
4747
}
4848

49-
function visitAttributes () {
49+
function visitAttributesAndAddProps () {
5050
let intro;
5151
let outro;
5252

@@ -63,6 +63,37 @@ export default function visitElement ( generator, block, state, node ) {
6363
});
6464

6565
if ( intro || outro ) addTransitions( generator, block, childState, node, intro, outro );
66+
67+
if ( childState.allUsedContexts.length || childState.usesComponent ) {
68+
const initialProps = [];
69+
const updates = [];
70+
71+
if ( childState.usesComponent ) {
72+
initialProps.push( `component: ${block.component}` );
73+
}
74+
75+
childState.allUsedContexts.forEach( contextName => {
76+
if ( contextName === 'state' ) return;
77+
78+
const listName = block.listNames.get( contextName );
79+
const indexName = block.indexNames.get( contextName );
80+
81+
initialProps.push( `${listName}: ${listName},\n${indexName}: ${indexName}` );
82+
updates.push( `${name}._svelte.${listName} = ${listName};\n${name}._svelte.${indexName} = ${indexName};` );
83+
});
84+
85+
if ( initialProps.length ) {
86+
block.builders.create.addBlock( deindent`
87+
${name}._svelte = {
88+
${initialProps.join( ',\n' )}
89+
};
90+
` );
91+
}
92+
93+
if ( updates.length ) {
94+
block.builders.update.addBlock( updates.join( '\n' ) );
95+
}
96+
}
6697
}
6798

6899
if ( !state.parentNode ) {
@@ -74,7 +105,7 @@ export default function visitElement ( generator, block, state, node ) {
74105
if ( node.name !== 'select' ) {
75106
// <select> value attributes are an annoying special case — it must be handled
76107
// *after* its children have been updated
77-
visitAttributes();
108+
visitAttributesAndAddProps();
78109
}
79110

80111
// special case – bound <option> without a value attribute
@@ -83,37 +114,6 @@ export default function visitElement ( generator, block, state, node ) {
83114
node.initialUpdate = node.lateUpdate = statement;
84115
}
85116

86-
if ( childState.allUsedContexts.length || childState.usesComponent ) {
87-
const initialProps = [];
88-
const updates = [];
89-
90-
if ( childState.usesComponent ) {
91-
initialProps.push( `component: ${block.component}` );
92-
}
93-
94-
childState.allUsedContexts.forEach( contextName => {
95-
if ( contextName === 'state' ) return;
96-
97-
const listName = block.listNames.get( contextName );
98-
const indexName = block.indexNames.get( contextName );
99-
100-
initialProps.push( `${listName}: ${listName},\n${indexName}: ${indexName}` );
101-
updates.push( `${name}._svelte.${listName} = ${listName};\n${name}._svelte.${indexName} = ${indexName};` );
102-
});
103-
104-
if ( initialProps.length ) {
105-
block.builders.create.addBlock( deindent`
106-
${name}._svelte = {
107-
${initialProps.join( ',\n' )}
108-
};
109-
` );
110-
}
111-
112-
if ( updates.length ) {
113-
block.builders.update.addBlock( updates.join( '\n' ) );
114-
}
115-
}
116-
117117
node.children.forEach( child => {
118118
visit( generator, block, childState, child );
119119
});
@@ -123,7 +123,7 @@ export default function visitElement ( generator, block, state, node ) {
123123
}
124124

125125
if ( node.name === 'select' ) {
126-
visitAttributes();
126+
visitAttributesAndAddProps();
127127
}
128128

129129
if ( node.initialUpdate ) {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
export default {
2+
test ( assert, component, target, window ) {
3+
const selects = document.querySelectorAll( 'select' );
4+
5+
const event1 = new window.Event( 'change' );
6+
selects[0].value = 'b';
7+
selects[0].dispatchEvent(event1);
8+
9+
const event2 = new window.Event( 'change' );
10+
selects[1].value = 'b';
11+
selects[1].dispatchEvent(event2);
12+
13+
assert.deepEqual( component.get( 'log' ), [ 1, 2 ] );
14+
}
15+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
{{#each foo as bar}}
2+
<select on:change='handler(bar)'>
3+
<option>a</option>
4+
<option>b</option>
5+
</select>
6+
{{/each}}
7+
8+
<script>
9+
export default {
10+
data: () => ({ foo: [ 1, 2 ], log: [] }),
11+
methods: {
12+
handler ( bar ) {
13+
let { log } = this.get();
14+
log.push( bar );
15+
this.set( { log } );
16+
}
17+
}
18+
}
19+
</script>

0 commit comments

Comments
 (0)