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