Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

use regular DOM patching when unlocking cloned trees #3652

Merged
merged 2 commits into from
Jan 26, 2025

Conversation

SteffenDE
Copy link
Collaborator

@SteffenDE SteffenDE commented Jan 24, 2025

Fixes #3647.
Fixes #3651.
Relates to: #3591.

Issue #3647 was caused by LV uploads relying on DOM attributes like
data-phx-active-refs="1,2,3" being in the DOM to track uploads. The problem
arises when the upload input is inside a form that is locked due to another,
unrelated change. The following would happen:

  1. User clicks on a button to upload a file
  2. A hook calls this.uploadTo(), which triggers a validate event and
    locks the form
  3. The hook also changes another input in ANOTHER form, which also
    triggers a separate validate event and locks the form
  4. The first validate completes, but the attributes are patched to the
    clone of the form, the real DOM does not contain it.
  5. LiveView tries to start uploading, but does not find any active files.

This case is special in that the upload input belongs to a separate form
(<input form="form-id">), so it's not the upload input's form that is locked.

The fix for this is to only try to upload when the closest locked element
starting from the upload input is unlocked.

There was a separate problem though: LiveView relied on a separate DOM
patching mechanism when patching cloned trees that did not fully share
the same logic as the default DOMPatch. In this case, it did not merge
data-attributes on elements that are ignored
(phx-update="ignore" / data-phx-update="ignore"), therefore, the first
fix alone would not work.

Now, we use the same patching logic for regular DOM patches and element
unlocks.

This difference in DOM patching logic also caused other issues, notably:

Fixes #3647.
Fixes #3651.
Relates to: #3591.

Issue #3647 was caused by LV uploads relying on DOM attributes like
data-phx-active-refs="1,2,3" being in the DOM to track uploads. The problem
arises when the upload input is inside a form that is locked due to another,
unrelated change. The following would happen:

1. User clicks on a button to upload a file
2. A hook calls this.uploadTo(), which triggers a validate event and
   locks the form
3. The hook also changes another input in ANOTHER form, which also
   triggers a separate validate event and locks the form
4. The first validate completes, but the attributes are patched to the
   clone of the form, the real DOM does not contain it.
5. LiveView tries to start uploading, but does not find any active files.

This case is special in that the upload input belongs to a separate form
(<input form="form-id">), so it's not the upload input's form that is locked.

The fix for this is to only try to upload when the closest locked element
starting from the upload input is unlocked.

There was a separate problem though: LiveView relied on a separate DOM
patching mechanism when patching cloned trees that did not fully share
the same logic as the default DOMPatch. In this case, it did not merge
data-attributes on elements that are ignored
(phx-update="ignore" / data-phx-update="ignore"), therefore, the first
fix alone would not work.

Now, we use the same patching logic for regular DOM patches and element
unlocks.

This difference in DOM patching logic also caused other issues, notably:
   * #3591
   * #3651
@marcandre
Copy link
Contributor

marcandre commented Jan 24, 2025

Wow, awesome. This makes me feel so appreciative that some people can figure this out, seems like it would take me a lifetime! ❤️

I was hopeful this would resolve our more serious issues with some of our fields clearing / LV's state being totally corrupted in difficult to minimize circumstances. Unfortunately, I am sad to report that even when using this patch, that bug remains 😭. I'll have to think on how I can report that one in a useful manner. 😢

@SteffenDE
Copy link
Collaborator Author

@marcandre thank you! I hoped that this would fix your other issues as well :(

You could try to bisect the repo (clone it somewhere and use it as path dependency), then, before testing run mix assets.build to build the LV assets. Finding out which change introduced your issues would probably help a lot.

Copy link
Member

@josevalim josevalim left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Amazing!

@marcandre
Copy link
Contributor

My bad 🤦‍♂️. When testing I was trying this branch, but I needed to build the assets too. With the assets build, my complex integration test that led to field clearing and LV state corruption is fixed 🎉.

Fabulous ❤️ 🕺 Thank you so much @SteffenDE

@SteffenDE
Copy link
Collaborator Author

Oh, I should have mentioned that assets are only updated after merge.. Anyway, very happy to hear!

@SteffenDE SteffenDE merged commit 22ff924 into main Jan 26, 2025
16 checks passed
@SteffenDE SteffenDE deleted the sd-clone-full-patch branch January 26, 2025 15:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Hooks with dynamic ID are not properly destroyed LiveView 1.0 introduced update issue with autostart uploads
3 participants