mirror of https://github.com/sveltejs/svelte
fix: use local mutable sources for props in legacy mode in case they are indirectly invalidated (#16038)
* fix: use local mutable sources for props in legacy mode in case they are indirectly invalidated * rename test * add another test * fix * more conservative * Update .changeset/orange-tips-pull.md * skip work in runes mode * remove comment * revert whitespace changepull/16045/head
parent
2f90dd8246
commit
54990f2329
@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
'svelte': patch
|
||||||
|
---
|
||||||
|
|
||||||
|
fix: treat transitive dependencies of each blocks as mutable in legacy mode if item is mutated
|
@ -0,0 +1,156 @@
|
|||||||
|
import { flushSync } from 'svelte';
|
||||||
|
import { test } from '../../test';
|
||||||
|
|
||||||
|
export default test({
|
||||||
|
get props() {
|
||||||
|
return {
|
||||||
|
items: [
|
||||||
|
{ done: false, text: 'one' },
|
||||||
|
{ done: true, text: 'two' },
|
||||||
|
{ done: false, text: 'three' }
|
||||||
|
]
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
html: `
|
||||||
|
<div>
|
||||||
|
<input type="checkbox">
|
||||||
|
<input type="text"><p>one</p>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<input type="checkbox">
|
||||||
|
<input type="text"><p>two</p>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<input type="checkbox">
|
||||||
|
<input type="text"><p>three</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<p>remaining:one / done:two / remaining:three</p>
|
||||||
|
`,
|
||||||
|
|
||||||
|
ssrHtml: `
|
||||||
|
<div>
|
||||||
|
<input type="checkbox">
|
||||||
|
<input type="text" value=one><p>one</p>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<input type="checkbox" checked="">
|
||||||
|
<input type="text" value=two><p>two</p>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<input type="checkbox">
|
||||||
|
<input type="text" value=three><p>three</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<p>remaining:one / done:two / remaining:three</p>
|
||||||
|
`,
|
||||||
|
|
||||||
|
test({ assert, component, target, window }) {
|
||||||
|
/**
|
||||||
|
* @param {number} i
|
||||||
|
* @param {string} text
|
||||||
|
*/
|
||||||
|
function set_text(i, text) {
|
||||||
|
const input = /** @type {HTMLInputElement} */ (
|
||||||
|
target.querySelectorAll('input[type="text"]')[i]
|
||||||
|
);
|
||||||
|
input.value = text;
|
||||||
|
input.dispatchEvent(new window.Event('input'));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {number} i
|
||||||
|
* @param {boolean} done
|
||||||
|
*/
|
||||||
|
function set_done(i, done) {
|
||||||
|
const input = /** @type {HTMLInputElement} */ (
|
||||||
|
target.querySelectorAll('input[type="checkbox"]')[i]
|
||||||
|
);
|
||||||
|
input.checked = done;
|
||||||
|
input.dispatchEvent(new window.Event('change'));
|
||||||
|
}
|
||||||
|
|
||||||
|
component.filter = 'remaining';
|
||||||
|
|
||||||
|
assert.htmlEqual(
|
||||||
|
target.innerHTML,
|
||||||
|
`
|
||||||
|
<div>
|
||||||
|
<input type="checkbox">
|
||||||
|
<input type="text"><p>one</p>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<input type="checkbox">
|
||||||
|
<input type="text"><p>three</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<p>remaining:one / done:two / remaining:three</p>
|
||||||
|
`
|
||||||
|
);
|
||||||
|
|
||||||
|
set_text(1, 'four');
|
||||||
|
flushSync();
|
||||||
|
|
||||||
|
assert.htmlEqual(
|
||||||
|
target.innerHTML,
|
||||||
|
`
|
||||||
|
<div>
|
||||||
|
<input type="checkbox">
|
||||||
|
<input type="text"><p>one</p>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<input type="checkbox">
|
||||||
|
<input type="text"><p>four</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<p>remaining:one / done:two / remaining:four</p>
|
||||||
|
`
|
||||||
|
);
|
||||||
|
|
||||||
|
assert.deepEqual(component.items, [
|
||||||
|
{ done: false, text: 'one' },
|
||||||
|
{ done: true, text: 'two' },
|
||||||
|
{ done: false, text: 'four' }
|
||||||
|
]);
|
||||||
|
|
||||||
|
set_done(0, true);
|
||||||
|
flushSync();
|
||||||
|
|
||||||
|
assert.htmlEqual(
|
||||||
|
target.innerHTML,
|
||||||
|
`
|
||||||
|
<div>
|
||||||
|
<input type="checkbox">
|
||||||
|
<input type="text"><p>four</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<p>done:one / done:two / remaining:four</p>
|
||||||
|
`
|
||||||
|
);
|
||||||
|
|
||||||
|
assert.deepEqual(component.items, [
|
||||||
|
{ done: true, text: 'one' },
|
||||||
|
{ done: true, text: 'two' },
|
||||||
|
{ done: false, text: 'four' }
|
||||||
|
]);
|
||||||
|
|
||||||
|
component.filter = 'done';
|
||||||
|
|
||||||
|
assert.htmlEqual(
|
||||||
|
target.innerHTML,
|
||||||
|
`
|
||||||
|
<div>
|
||||||
|
<input type="checkbox">
|
||||||
|
<input type="text"><p>one</p>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<input type="checkbox">
|
||||||
|
<input type="text"><p>two</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<p>done:one / done:two / remaining:four</p>
|
||||||
|
`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
@ -0,0 +1,25 @@
|
|||||||
|
<script>
|
||||||
|
export let items;
|
||||||
|
export let filter = 'all';
|
||||||
|
|
||||||
|
$: done = items.filter(item => item.done);
|
||||||
|
$: remaining = items.filter(item => !item.done);
|
||||||
|
|
||||||
|
$: filtered = (
|
||||||
|
filter === 'all' ? items :
|
||||||
|
filter === 'done' ? done :
|
||||||
|
remaining
|
||||||
|
);
|
||||||
|
|
||||||
|
$: summary = items.map(i => `${i.done ? 'done' : 'remaining'}:${i.text}`).join(' / ');
|
||||||
|
</script>
|
||||||
|
|
||||||
|
{#each filtered as item}
|
||||||
|
<div>
|
||||||
|
<input type="checkbox" bind:checked={item.done}>
|
||||||
|
<input type="text" bind:value={item.text}>
|
||||||
|
<p>{item.text}</p>
|
||||||
|
</div>
|
||||||
|
{/each}
|
||||||
|
|
||||||
|
<p>{summary}</p>
|
Loading…
Reference in new issue