mirror of https://github.com/sveltejs/svelte
prevent infinite loops caused by pathological component bindings (#398)
parent
8ff2de90be
commit
1780876b99
@ -0,0 +1,12 @@
|
||||
<B bind:currentIdentifier />
|
||||
<B bind:currentIdentifier />
|
||||
|
||||
<script>
|
||||
import B from './B.html';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
B
|
||||
}
|
||||
}
|
||||
</script>
|
@ -0,0 +1,20 @@
|
||||
{{#each list as item}}
|
||||
<p>
|
||||
<C identifier="{{item}}" bind:currentIdentifier>
|
||||
{{item}}
|
||||
</C>
|
||||
</p>
|
||||
{{/each}}
|
||||
|
||||
<script>
|
||||
import C from './C.html';
|
||||
|
||||
export default {
|
||||
data: () => ({
|
||||
list: [1, 2, 3, 2, 1]
|
||||
}),
|
||||
components: {
|
||||
C
|
||||
}
|
||||
}
|
||||
</script>
|
@ -0,0 +1,23 @@
|
||||
<span
|
||||
on:click="toggle()"
|
||||
class="{{isCurrentlySelected ? 'selected' : ''}}"
|
||||
>
|
||||
{{yield}}
|
||||
</span>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
computed: {
|
||||
isCurrentlySelected: (currentIdentifier, identifier) => currentIdentifier === identifier
|
||||
},
|
||||
methods: {
|
||||
toggle() {
|
||||
const isCurrentlySelected = this.get('isCurrentlySelected')
|
||||
|
||||
this.set({
|
||||
currentIdentifier: isCurrentlySelected ? null : this.get('identifier')
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
@ -0,0 +1,90 @@
|
||||
export default {
|
||||
html: `
|
||||
<p><span class=''>1</span></p>
|
||||
<p><span class='selected'>2</span></p>
|
||||
<p><span class=''>3</span></p>
|
||||
<p><span class='selected'>2</span></p>
|
||||
<p><span class=''>1</span></p>
|
||||
|
||||
<p><span class=''>1</span></p>
|
||||
<p><span class='selected'>2</span></p>
|
||||
<p><span class=''>3</span></p>
|
||||
<p><span class='selected'>2</span></p>
|
||||
<p><span class=''>1</span></p>
|
||||
|
||||
<p><span class=''>1</span></p>
|
||||
<p><span class='selected'>2</span></p>
|
||||
<p><span class=''>3</span></p>
|
||||
<p><span class='selected'>2</span></p>
|
||||
<p><span class=''>1</span></p>
|
||||
|
||||
<p><span class=''>1</span></p>
|
||||
<p><span class='selected'>2</span></p>
|
||||
<p><span class=''>3</span></p>
|
||||
<p><span class='selected'>2</span></p>
|
||||
<p><span class=''>1</span></p>
|
||||
`,
|
||||
|
||||
test ( assert, component, target, window ) {
|
||||
const click = new window.MouseEvent( 'click' );
|
||||
const spans = target.querySelectorAll( 'span' );
|
||||
|
||||
spans[0].dispatchEvent( click );
|
||||
|
||||
assert.equal( component.get( 'currentIdentifier' ), 1 );
|
||||
assert.htmlEqual( target.innerHTML, `
|
||||
<p><span class='selected'>1</span></p>
|
||||
<p><span class=''>2</span></p>
|
||||
<p><span class=''>3</span></p>
|
||||
<p><span class=''>2</span></p>
|
||||
<p><span class='selected'>1</span></p>
|
||||
|
||||
<p><span class='selected'>1</span></p>
|
||||
<p><span class=''>2</span></p>
|
||||
<p><span class=''>3</span></p>
|
||||
<p><span class=''>2</span></p>
|
||||
<p><span class='selected'>1</span></p>
|
||||
|
||||
<p><span class='selected'>1</span></p>
|
||||
<p><span class=''>2</span></p>
|
||||
<p><span class=''>3</span></p>
|
||||
<p><span class=''>2</span></p>
|
||||
<p><span class='selected'>1</span></p>
|
||||
|
||||
<p><span class='selected'>1</span></p>
|
||||
<p><span class=''>2</span></p>
|
||||
<p><span class=''>3</span></p>
|
||||
<p><span class=''>2</span></p>
|
||||
<p><span class='selected'>1</span></p>
|
||||
` );
|
||||
|
||||
spans[0].dispatchEvent( click );
|
||||
|
||||
assert.equal( component.get( 'currentIdentifier' ), null );
|
||||
assert.htmlEqual( target.innerHTML, `
|
||||
<p><span class=''>1</span></p>
|
||||
<p><span class=''>2</span></p>
|
||||
<p><span class=''>3</span></p>
|
||||
<p><span class=''>2</span></p>
|
||||
<p><span class=''>1</span></p>
|
||||
|
||||
<p><span class=''>1</span></p>
|
||||
<p><span class=''>2</span></p>
|
||||
<p><span class=''>3</span></p>
|
||||
<p><span class=''>2</span></p>
|
||||
<p><span class=''>1</span></p>
|
||||
|
||||
<p><span class=''>1</span></p>
|
||||
<p><span class=''>2</span></p>
|
||||
<p><span class=''>3</span></p>
|
||||
<p><span class=''>2</span></p>
|
||||
<p><span class=''>1</span></p>
|
||||
|
||||
<p><span class=''>1</span></p>
|
||||
<p><span class=''>2</span></p>
|
||||
<p><span class=''>3</span></p>
|
||||
<p><span class=''>2</span></p>
|
||||
<p><span class=''>1</span></p>
|
||||
` );
|
||||
}
|
||||
};
|
@ -0,0 +1,17 @@
|
||||
<A bind:currentIdentifier />
|
||||
<A bind:currentIdentifier />
|
||||
|
||||
<script>
|
||||
import A from './A.html';
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
currentIdentifier: 2
|
||||
}
|
||||
},
|
||||
components: {
|
||||
A
|
||||
}
|
||||
}
|
||||
</script>
|
Loading…
Reference in new issue