mirror of https://github.com/sveltejs/svelte
fix: don't execute attachments and attribute effects eagerly (#17208)
* fix: don't execute attachments and attribute effects eagerly attributes_effect and attachments are blocks since they need the managed "don't just destroy children effects"-behavior, but they're not block effects in the sense of "run them eagerly while traversing the effect tree or while flushing effects". Since the latter was the case until now, it meant that forks could cause visible UI updates. This PR introduces a new flag to fix that. `BLOCK_NON_EAGER` is basically a combination of block effects (with respects to the managed behavior) and render effects (with respects to the execution timing). Fixes https://github.com/sveltejs/kit/issues/14931 * managed_effectpull/17229/head
parent
1aafbc47ff
commit
53bbe3462b
@ -0,0 +1,5 @@
|
||||
---
|
||||
'svelte': patch
|
||||
---
|
||||
|
||||
fix: don't execute attachments and attribute effects eagerly
|
||||
@ -0,0 +1,60 @@
|
||||
import { tick } from 'svelte';
|
||||
import { test } from '../../test';
|
||||
|
||||
export default test({
|
||||
async test({ assert, target }) {
|
||||
const [fork, commit] = target.querySelectorAll('button');
|
||||
|
||||
fork.click();
|
||||
await tick();
|
||||
assert.htmlEqual(
|
||||
target.innerHTML,
|
||||
`
|
||||
<button>fork</button>
|
||||
<button>commit</button>
|
||||
<p style="">foo</p>
|
||||
<p style="">foo</p>
|
||||
<p>foo</p>
|
||||
`
|
||||
);
|
||||
|
||||
commit.click();
|
||||
await tick();
|
||||
assert.htmlEqual(
|
||||
target.innerHTML,
|
||||
`
|
||||
<button>fork</button>
|
||||
<button>commit</button>
|
||||
<p style="color: red;">foo</p>
|
||||
<p style="color: red;" data-attached=true>foo</p>
|
||||
<p data-attached=true>foo</p>
|
||||
`
|
||||
);
|
||||
|
||||
fork.click();
|
||||
await tick();
|
||||
assert.htmlEqual(
|
||||
target.innerHTML,
|
||||
`
|
||||
<button>fork</button>
|
||||
<button>commit</button>
|
||||
<p style="color: red;">foo</p>
|
||||
<p style="color: red;" data-attached=true>foo</p>
|
||||
<p data-attached=true>foo</p>
|
||||
`
|
||||
);
|
||||
|
||||
commit.click();
|
||||
await tick();
|
||||
assert.htmlEqual(
|
||||
target.innerHTML,
|
||||
`
|
||||
<button>fork</button>
|
||||
<button>commit</button>
|
||||
<p style="">foo</p>
|
||||
<p style="">foo</p>
|
||||
<p>foo</p>
|
||||
`
|
||||
);
|
||||
}
|
||||
});
|
||||
@ -0,0 +1,28 @@
|
||||
<script>
|
||||
import { fork } from "svelte";
|
||||
import { createAttachmentKey } from "svelte/attachments";
|
||||
|
||||
let style = $state('');
|
||||
let attach = $state(undefined);
|
||||
|
||||
let forked;
|
||||
</script>
|
||||
|
||||
<button onclick={()=>{
|
||||
forked = fork(()=>{
|
||||
style = style ? '' : 'color: red';
|
||||
attach = attach ? undefined : (node) => {
|
||||
node.setAttribute('data-attached', 'true');
|
||||
return () => node.removeAttribute('data-attached');
|
||||
};
|
||||
})
|
||||
}}>fork</button>
|
||||
|
||||
<button onclick={()=>{
|
||||
forked.commit();
|
||||
}}>commit</button>
|
||||
|
||||
<!-- force $.attribute_effect, which uses a block effect -->
|
||||
<p {...{style}}>foo</p>
|
||||
<p {...{style, [createAttachmentKey()]: attach}}>foo</p>
|
||||
<p {@attach attach}>foo</p>
|
||||
Loading…
Reference in new issue