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