From 2fe7e990b4299853acbf1f28bae86074e7e966ec Mon Sep 17 00:00:00 2001 From: Jay Ohms Date: Thu, 22 Feb 2024 17:50:01 -0500 Subject: [PATCH] Fix the implementation so it properly works for Turbo 8 refreshes without any flickering. Use Turbo.navigator.location to determine the current location, so it works immediately cold boots and Turbo visits --- turbo/src/main/assets/js/turbo_bridge.js | 3 ++ .../dev/hotwire/turbo/session/TurboSession.kt | 30 +++++++++++-------- .../hotwire/turbo/session/TurboSessionTest.kt | 11 ------- 3 files changed, 20 insertions(+), 24 deletions(-) diff --git a/turbo/src/main/assets/js/turbo_bridge.js b/turbo/src/main/assets/js/turbo_bridge.js index 9b5053c8..67e6fe54 100644 --- a/turbo/src/main/assets/js/turbo_bridge.js +++ b/turbo/src/main/assets/js/turbo_bridge.js @@ -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)) diff --git a/turbo/src/main/kotlin/dev/hotwire/turbo/session/TurboSession.kt b/turbo/src/main/kotlin/dev/hotwire/turbo/session/TurboSession.kt index 5c830631..7887fa16 100644 --- a/turbo/src/main/kotlin/dev/hotwire/turbo/session/TurboSession.kt +++ b/turbo/src/main/kotlin/dev/hotwire/turbo/session/TurboSession.kt @@ -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) } /** diff --git a/turbo/src/test/kotlin/dev/hotwire/turbo/session/TurboSessionTest.kt b/turbo/src/test/kotlin/dev/hotwire/turbo/session/TurboSessionTest.kt index 1216e2d8..0abde2e0 100644 --- a/turbo/src/test/kotlin/dev/hotwire/turbo/session/TurboSessionTest.kt +++ b/turbo/src/test/kotlin/dev/hotwire/turbo/session/TurboSessionTest.kt @@ -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"