[fix] race condition in svelte:element with transition #7948
Fix for #7948
- The assignment of the variable "previous_tag" was incorrectly positioned and could cause race condition when used with transitions.
- We need another variable to detect when we are in a transition to remove a node
Previous generated code :
p(ctx, [dirty]) {
if (!current || dirty & /*tag*/ 1) set_data(t2, /*tag*/ ctx[0]);
if (/*tag*/ ctx[0]) {
if (!previous_tag) {
svelte_element = create_dynamic_element(ctx);
svelte_element.c();
transition_in(svelte_element);
svelte_element.m(div, null);
} else if (safe_not_equal(previous_tag, /*tag*/ ctx[0])) {
svelte_element.d(1);
svelte_element = create_dynamic_element(ctx);
svelte_element.c();
svelte_element.m(div, null);
} else {
svelte_element.p(ctx, dirty);
}
} else if (previous_tag) {
group_outros();
transition_out(svelte_element, 1, 1, () => {
svelte_element = null;
});
check_outros();
}
previous_tag = /*tag*/ ctx[0];
},
New generated code :
p: function update(ctx, [dirty]) {
if (!current || dirty & /*tag*/ 1) set_data_dev(t2, /*tag*/ ctx[0]);
if (/*tag*/ ctx[0]) {
if (!previous_tag) {
svelte_element = create_dynamic_element(ctx);
previous_tag = /*tag*/ ctx[0];
svelte_element.c();
transition_in(svelte_element);
svelte_element.m(div, null);
} else if (safe_not_equal(previous_tag, /*tag*/ ctx[0])) {
svelte_element.d(1);
validate_dynamic_element(/*tag*/ ctx[0]);
validate_void_dynamic_element(/*tag*/ ctx[0]);
svelte_element = create_dynamic_element(ctx);
previous_tag = /*tag*/ ctx[0];
svelte_element.c();
if (tag_will_be_removed) {
tag_will_be_removed = false;
transition_in(svelte_element);
}
svelte_element.m(div, null);
} else {
if (tag_will_be_removed) {
tag_will_be_removed = false;
transition_in(svelte_element);
}
svelte_element.p(ctx, dirty);
}
} else if (previous_tag) {
tag_will_be_removed = true;
group_outros();
transition_out(svelte_element, 1, 1, () => {
svelte_element = null;
previous_tag = /*tag*/ ctx[0];
tag_will_be_removed = false;
});
check_outros();
}
},
Before submitting the PR, please make sure you do the following
- [X] It's really useful if your PR references an issue where it is discussed ahead of time. In many cases, features are absent for a reason. For large changes, please create an RFC: https://github.com/sveltejs/rfcs
- [X] Prefix your PR title with
[feat],[fix],[chore], or[docs]. - [ ] This message body should clearly illustrate what problems it solves.
- [ ] Ideally, include a test that fails without this PR but passes with it.
Tests
- [X] Run the tests with
npm testand lint the project withnpm run lint
I also modified the generation of update() code, which is useless when the tag is not dynamic. In this case the generated code will correspond to this:
p: function update(ctx, [dirty]) {
if (svelte_element) svelte_element.p(ctx, dirty);
},
I also edited an unit test for ajusting the expected result accordingly.
I merged with the lastest master and it fixed the test error...
Should I do something ? (I'm not familiar with these processes)
Sorry for the late response. I added a test !
I would be very happy if you could resolve the conflict.
@adiguba a reminder that there's a merge conflict on this PR. Thanks!
@baseballyama is attempting to deploy a commit to the Svelte Team on Vercel.
A member of the Team first needs to authorize it.
@benmccann : I'm sorry I don't know how to do that :(
You can sync it with the latest code using the following commands:
git remote add upstream [email protected]:sveltejs/svelte.git
git fetch upstream
git merge upstream/master
Thanks !
I think it's good now.
Tests are OK
The latest updates on your projects. Learn more about Vercel for Git ↗︎
| Name | Status | Preview | Comments | Updated |
|---|---|---|---|---|
| svelte-dev-2 | ❌ Failed (Inspect) | Feb 23, 2023 at 9:14PM (UTC) |
I forgot to run "lint"... :/
Thank you!
Great !