svelte icon indicating copy to clipboard operation
svelte copied to clipboard

[fix] race condition in svelte:element with transition #7948

Open adiguba opened this issue 3 years ago • 3 comments

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 test and lint the project with npm run lint

adiguba avatar Oct 14 '22 20:10 adiguba

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.

adiguba avatar Oct 14 '22 21:10 adiguba

I merged with the lastest master and it fixed the test error...

adiguba avatar Oct 18 '22 18:10 adiguba

Should I do something ? (I'm not familiar with these processes)

adiguba avatar Nov 01 '22 07:11 adiguba

Sorry for the late response. I added a test !

adiguba avatar Dec 29 '22 17:12 adiguba

I would be very happy if you could resolve the conflict.

baseballyama avatar Jan 02 '23 06:01 baseballyama

@adiguba a reminder that there's a merge conflict on this PR. Thanks!

benmccann avatar Feb 22 '23 04:02 benmccann

@baseballyama is attempting to deploy a commit to the Svelte Team on Vercel.

A member of the Team first needs to authorize it.

vercel[bot] avatar Feb 23 '23 15:02 vercel[bot]

@benmccann : I'm sorry I don't know how to do that :(

adiguba avatar Feb 23 '23 20:02 adiguba

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

benmccann avatar Feb 23 '23 20:02 benmccann

Thanks !

I think it's good now.

Tests are OK

adiguba avatar Feb 23 '23 20:02 adiguba

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)

vercel[bot] avatar Feb 23 '23 21:02 vercel[bot]

I forgot to run "lint"... :/

adiguba avatar Feb 23 '23 21:02 adiguba

Thank you!

dummdidumm avatar Feb 27 '23 12:02 dummdidumm

Great !

adiguba avatar Feb 27 '23 12:02 adiguba