Fix page loads when refreshing location with anchor - #324
Conversation
|
@domchristie Thanks, this looks like an improvement 👍. I'm wondering if this covers all situations here:
Say you're on page |
|
Another idea is to validate that the #anchor element exists on the page before considering it a same-page visit. |
@jayohms Unfortunately not. This PR was inspired by that feedback, but will only perform a full visit if the locations are identical—with a nice side-effect of simplifying the code (I'm not sure why I didn't think of this approach before!)
Interesting! I've been mulling over a fix for this, and to summarise the options:
I think I prefer your options as they elegantly don't require additional API. Just wondering if they cover all situations? For example, let's say that rather than Re. option 1: I'm struggling to think of a reason why someone would intentionally perform a same-page I could be wrongly second-guessing people's intentions for same-page visits, but the more I think about it, the more I think option 1 (plus perhaps 2), will cover most situations. |
Yeah, I'd like to avoid new APIs if possible, too. In this situation, I think it's ok to say a
I can't think of any negative consequences here, either.
Yeah, I think so too. I think we should try solutions 1 and 2 together, because then by default it'll handle the situation where you try to visit a new anchor that doesn't currently exist, i.e. |
Solution 1 is currently complete in this PR. Part 2 might require a bit more thought. I haven't fully got my head round it, but the logic might get complex if we consider blank/ |
|
Thanks @domchristie! I haven't really considered the implementation for solution 2. If it looks like it's going to be complex, consider splitting into a separate PR that we can evaluate separately. |
Now I do! … If we only check the hash changes, then navigating from So this results in a pretty gnarly check: locationWithActionIsSamePage(location: URL, action: Action): boolean {
const anchor = getAnchor(location)
const currentAnchor = getAnchor(this.view.lastRenderedLocation)
const restoreToTop = action === 'restore' && typeof anchor === 'undefined'
const anchorElementExists = anchor === '' || this.view.snapshot.hasAnchor(anchor)
return action !== "replace" &&
getRequestURL(location) === getRequestURL(this.view.lastRenderedLocation) &&
(
restoreToTop ||
(anchor != null && anchor !== currentAnchor && anchorElementExists)
)
}:/ |
|
Still in two minds about validating whether an element exists. It's cool, but it feels a bit odd given that a browser will just scroll to the top. |
6e48897 to
4eb3720
Compare
jayohms
left a comment
There was a problem hiding this comment.
Still in two minds about validating whether an element exists. It's cool, but it feels a bit odd given that a browser will just scroll to the top.
Yeah, totally fine leaving out for now. If we hear feedback on it, we can reevaluate 👍.
Thanks for doing this, looks great!
Great, rebasing now… |
4eb3720 to
fab846b
Compare
The likelihood is that a same-page replace visit will want to load a fresh version from the server
An alternative to hotwired#268
Update the same-page check, making it possible to refresh a location such as example.com#main
fab846b to
a308970
Compare
|
@jayohms Done. (I think that failing test is a flaky one) |
Currently, if the location is
http://example.com#main, and we callTurbo.visit(location.toString()), the page will just scroll to the anchor without reloading the page. This makes is impossible to refresh a current page via a Turbo visit.Rather than checking for the presence of a URL hash, this pull request just checks that the hash has changed. If so, it's a same page visit.
/cc @jayohms