Skip to content

Commit

Permalink
Fix the implementation so it properly works for Turbo 8 refreshes wit…
Browse files Browse the repository at this point in the history
…hout any flickering. Use Turbo.navigator.location to determine the current location, so it works immediately cold boots and Turbo visits
  • Loading branch information
jayohms committed Feb 22, 2024
1 parent 0cd4e6d commit 2fe7e99
Show file tree
Hide file tree
Showing 3 changed files with 20 additions and 24 deletions.
3 changes: 3 additions & 0 deletions turbo/src/main/assets/js/turbo_bridge.js
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,9 @@
// Scroll to the anchor on the page
TurboSession.visitProposalScrollingToAnchor(location.toString(), JSON.stringify(options))
Turbo.navigator.view.scrollToAnchorFromLocation(location)
} else if (Turbo.navigator.location.href === location.href) {
TurboSession.visitProposalIsPageRefresh(location.toString(), JSON.stringify(options))
this.visitLocationWithOptionsAndRestorationIdentifier(location, JSON.stringify(options), Turbo.navigator.restorationIdentifier)
} else {
// Propose the visit
TurboSession.visitProposedToLocation(location.toString(), JSON.stringify(options))
Expand Down
30 changes: 17 additions & 13 deletions turbo/src/main/kotlin/dev/hotwire/turbo/session/TurboSession.kt
Original file line number Diff line number Diff line change
Expand Up @@ -191,20 +191,24 @@ class TurboSession internal constructor(
fun visitProposedToLocation(location: String, optionsJson: String) {
val options = TurboVisitOptions.fromJSON(optionsJson) ?: return

val visit = currentVisit?.copy(
restoreWithCachedSnapshot = false,
options = options
)
logEvent("visitProposedToLocation", "location" to location, "options" to options)
callback { it.visitProposedToLocation(location, options) }
}

if (visit?.location == location) {
// Automatically re-visit the same page location
logEvent("visitProposedToSamePage", "location" to location, "options" to options)
visitLocation(visit)
} else {
// Propose the visit to the app to decide how to handle it
logEvent("visitProposedToLocation", "location" to location, "options" to options)
callback { it.visitProposedToLocation(location, options) }
}
/**
* Called by Turbo bridge when a new visit proposal will refresh the
* current page.
*
* Warning: This method is public so it can be used as a Javascript Interface.
* You should never call this directly as it could lead to unintended behavior.
*
* @param location The location to visit.
* @param optionsJson A JSON block to be serialized into [TurboVisitOptions].
*/
@JavascriptInterface
fun visitProposalIsPageRefresh(location: String, optionsJson: String) {
val options = TurboVisitOptions.fromJSON(optionsJson) ?: return
logEvent("visitProposalIsPageRefresh", "location" to location, "options" to options)
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,17 +73,6 @@ class TurboSessionTest {
verify(callback).visitProposedToLocation(newLocation, options)
}

@Test
fun visitProposedToSameLocationStartsVisit() {
val options = TurboVisitOptions()

session.currentVisit = visit
session.visitProposedToLocation(visit.location, options.toJson())

verify(callback, never()).visitProposedToLocation(visit.location, options)
verify(webView).visitLocation(visit.location, options, "")
}

@Test
fun visitStartedSavesCurrentVisitIdentifier() {
val visitIdentifier = "12345"
Expand Down

0 comments on commit 2fe7e99

Please sign in to comment.