-
Notifications
You must be signed in to change notification settings - Fork 955
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
Revert "Fix unnecessary remount when navigating back" #3513
Merged
Conversation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This reverts commit eaaff4c.
SteffenDE
added a commit
that referenced
this pull request
Nov 30, 2024
Fixes #3536. Browser history API strikes back (again). Because live navigation shares the id of the view between live navigations, the following scenario could happen: 1. User visits page 1 (initial nav) 2. User patches the page 3. User visits page 2 (live nav) 4. User patches the page 5. User uses browser back button (state from 3 -> live nav) 6. User uses browser back button (state from 2 -> PATCH) In step 6, the user is still on page 2, but LiveView would try to patch the page instead of performing a live navigation. This is only a problem if the two pages use the same underlying LiveView module, otherwise the patch request would fallback to a navigation. This commit "fixes" this by modifying the current history entry at step 2 to `redirect` before pushing the new state. This way, LiveView does a live navigation when popping the state in step 6. The underlying problem is that we cannot differentiate a forward from a backward navigation when handling a popstate. If we could, we'd be able to separately store the backwards and forwards navigation type. The current approach will also do a live navigation when navigating forward again, therefore if a user went back in history to step 1 and pressed forward, we now do a live navigation instead of a patch, therefore potentially losing state. See also #3513 (comment).
SteffenDE
added a commit
that referenced
this pull request
Nov 30, 2024
Relates to #3513. Browser history API strikes back (again). Because live navigation shares the id of the view between live navigations, the following scenario could happen: 1. User visits page 1 (state: initial) 2. User patches the page (state: patch) 3. User visits page 2 (state: redirect) 4. User patches the page (state: patch) 5. User uses browser back button (state from 3 -> live nav) 6. User uses browser back button (state from 2 -> PATCH) In step 6, the user is still on page 2, but LiveView would try to patch the page instead of performing a live navigation. This is only a problem if the two pages use the same underlying LiveView module, otherwise the patch request would fallback to a navigation. Also, we have an unnecessary live navigation instead of a patch at step 5. To fix this, we now differentiate if we are navigation backwards of forwards and store the corresponding `backType` in the history state to do the correct type of navigation on popState, which was already mentioned as an idea in #3513. ======================= 1. User visits page 1 (initial nav) state: initial pre-push: update state to {type: "patch"} 2. User patches the page post-push: push new state {type: "patch"} pre-push: update state to {type: "patch", backType: "redirect"} 3. User visits page 2 (live nav) post-push: new state {type: "redirect"} pre-push: update state to {type: "redirect", backType: "patch"} 4. User patches the page post-push: new state {type: "patch"} 5. User uses browser back button (popState backType "patch") -> patch from the patched page back to non-patched page 2. 6. User uses browser back button (popState backType "redirect") -> live nav from the page 2 to patched page 1 ======================= Finally, we can also prevent the unnecessary remount when navigating all the way back properly (see #3335).
SteffenDE
added a commit
that referenced
this pull request
Nov 30, 2024
Relates to #3513. Browser history API strikes back (again). Because live navigation shares the id of the view between live navigations, the following scenario could happen: 1. User visits page 1 (state: initial) 2. User patches the page (state: patch) 3. User visits page 2 (state: redirect) 4. User patches the page (state: patch) 5. User uses browser back button (state from 3 -> live nav) 6. User uses browser back button (state from 2 -> PATCH) In step 6, the user is still on page 2, but LiveView would try to patch the page instead of performing a live navigation. This is only a problem if the two pages use the same underlying LiveView module, otherwise the patch request would fallback to a navigation. Also, we have an unnecessary live navigation instead of a patch at step 5. To fix this, we now differentiate if we are navigation backwards of forwards and store the corresponding `backType` in the history state to do the correct type of navigation on popState, which was already mentioned as an idea in #3513. ======================= 1. User visits page 1 (initial nav) state: initial pre-push: update state to {type: "patch"} 2. User patches the page post-push: push new state {type: "patch"} pre-push: update state to {type: "patch", backType: "redirect"} 3. User visits page 2 (live nav) post-push: new state {type: "redirect"} pre-push: update state to {type: "redirect", backType: "patch"} 4. User patches the page post-push: new state {type: "patch"} 5. User uses browser back button (popState backType "patch") -> patch from the patched page back to non-patched page 2. 6. User uses browser back button (popState backType "redirect") -> live nav from the page 2 to patched page 1 ======================= Finally, we can also prevent the unnecessary remount when navigating all the way back properly (see #3335).
SteffenDE
added a commit
that referenced
this pull request
Nov 30, 2024
Fixes #3536. Relates to #3513. Browser history API strikes back (again). Because live navigation shares the id of the view between live navigations, the following scenario could happen: 1. User visits page 1 (state: initial) 2. User patches the page (state: patch) 3. User visits page 2 (state: redirect) 4. User patches the page (state: patch) 5. User uses browser back button (state from 3 -> live nav) 6. User uses browser back button (state from 2 -> PATCH) In step 6, the user is still on page 2, but LiveView would try to patch the page instead of performing a live navigation. This is only a problem if the two pages use the same underlying LiveView module, otherwise the patch request would fallback to a navigation. Also, we have an unnecessary live navigation instead of a patch at step 5. To fix this, we now differentiate if we are navigation backwards of forwards and store the corresponding `backType` in the history state to do the correct type of navigation on popState, which was already mentioned as an idea in #3513. ======================= 1. User visits page 1 (initial nav) state: initial pre-push: update state to {type: "patch"} 2. User patches the page post-push: push new state {type: "patch"} pre-push: update state to {type: "patch", backType: "redirect"} 3. User visits page 2 (live nav) post-push: new state {type: "redirect"} pre-push: update state to {type: "redirect", backType: "patch"} 4. User patches the page post-push: new state {type: "patch"} 5. User uses browser back button (popState backType "patch") -> patch from the patched page back to non-patched page 2. 6. User uses browser back button (popState backType "redirect") -> live nav from the page 2 to patched page 1 ======================= Finally, we can also prevent the unnecessary remount when navigating all the way back properly (see #3335).
SteffenDE
added a commit
that referenced
this pull request
Nov 30, 2024
Fixes #3536. Relates to #3513. Browser history API strikes back (again). Because live navigation shares the id of the view between live navigations, the following scenario could happen: 1. User visits page 1 (state: initial) 2. User patches the page (state: patch) 3. User visits page 2 (state: redirect) 4. User patches the page (state: patch) 5. User uses browser back button (state from 3 -> live nav) 6. User uses browser back button (state from 2 -> PATCH) In step 6, the user is still on page 2, but LiveView would try to patch the page instead of performing a live navigation. This is only a problem if the two pages use the same underlying LiveView module, otherwise the patch request would fallback to a navigation. Also, we have an unnecessary live navigation instead of a patch at step 5. To fix this, we now differentiate if we are navigation backwards of forwards and store the corresponding `backType` in the history state to do the correct type of navigation on popState, which was already mentioned as an idea in #3513. ======================= 1. User visits page 1 (initial nav) state: initial pre-push: update state to {type: "patch"} 2. User patches the page post-push: push new state {type: "patch"} pre-push: update state to {type: "patch", backType: "redirect"} 3. User visits page 2 (live nav) post-push: new state {type: "redirect"} pre-push: update state to {type: "redirect", backType: "patch"} 4. User patches the page post-push: new state {type: "patch"} 5. User uses browser back button (popState backType "patch") -> patch from the patched page back to non-patched page 2. 6. User uses browser back button (popState backType "redirect") -> live nav from the page 2 to patched page 1 ======================= Finally, we can also prevent the unnecessary remount when navigating all the way back properly (see #3335).
chrismccord
pushed a commit
that referenced
this pull request
Dec 2, 2024
Fixes #3536. Relates to #3513. Browser history API strikes back (again). Because live navigation shares the id of the view between live navigations, the following scenario could happen: 1. User visits page 1 (state: initial) 2. User patches the page (state: patch) 3. User visits page 2 (state: redirect) 4. User patches the page (state: patch) 5. User uses browser back button (state from 3 -> live nav) 6. User uses browser back button (state from 2 -> PATCH) In step 6, the user is still on page 2, but LiveView would try to patch the page instead of performing a live navigation. This is only a problem if the two pages use the same underlying LiveView module, otherwise the patch request would fallback to a navigation. Also, we have an unnecessary live navigation instead of a patch at step 5. To fix this, we now differentiate if we are navigation backwards of forwards and store the corresponding `backType` in the history state to do the correct type of navigation on popState, which was already mentioned as an idea in #3513. ======================= 1. User visits page 1 (initial nav) state: initial pre-push: update state to {type: "patch"} 2. User patches the page post-push: push new state {type: "patch"} pre-push: update state to {type: "patch", backType: "redirect"} 3. User visits page 2 (live nav) post-push: new state {type: "redirect"} pre-push: update state to {type: "redirect", backType: "patch"} 4. User patches the page post-push: new state {type: "patch"} 5. User uses browser back button (popState backType "patch") -> patch from the patched page back to non-patched page 2. 6. User uses browser back button (popState backType "redirect") -> live nav from the page 2 to patched page 1 ======================= Finally, we can also prevent the unnecessary remount when navigating all the way back properly (see #3335).
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Reverts #3335
Fixes #3508.
The history API is the worst...
replaceRootHistory sets the initial type to "patch". Now assuming the following events:
History:
Then we'd call replaceRootHistory after the new join:
If we now use the back button, the browser would send us a popstate event including the previous state (type=patch). Instead of a navigate, we'd do a patch.
We could change replaceRootHistory to not assume type=patch, but then the initial PR would be useless as well, as there would still be a remount when navigating back.
To properly fix this, we'd need a way to get the state from before the popstate event to determine what navigation type was used, but that's not possible. Another option would be to always update the current state before pushing a new one to include a
backType
that would be used when navigating in the other direction. But this would require us to be able to distinguish a back from a forward navigation, as we'd only want to use thebackType
when navigating back. There are ways to do this (https://stackoverflow.com/questions/8980255/how-do-i-retrieve-if-the-popstate-event-comes-from-back-or-forward-actions-with), but it's definitely not pretty and doesn't seem worth it imho.We might revisit this in the future, when the Navigation API is more widely available.