diff --git a/Source/Session/Session.swift b/Source/Session/Session.swift index 248ebb8..bcfdab3 100644 --- a/Source/Session/Session.swift +++ b/Source/Session/Session.swift @@ -164,12 +164,16 @@ extension Session: VisitDelegate { } func visitWillStart(_ visit: Visit) { + guard !visit.isPageRefresh else { return } + visit.visitable.showVisitableScreenshot() activateVisitable(visit.visitable) } func visitDidStart(_ visit: Visit) { guard !visit.hasCachedSnapshot else { return } + guard !visit.isPageRefresh else { return } + visit.visitable.showVisitableActivityIndicator() } diff --git a/Source/Visit/JavaScriptVisit.swift b/Source/Visit/JavaScriptVisit.swift index 97b442e..81ded55 100644 --- a/Source/Visit/JavaScriptVisit.swift +++ b/Source/Visit/JavaScriptVisit.swift @@ -34,10 +34,11 @@ final class JavaScriptVisit: Visit { } extension JavaScriptVisit: WebViewVisitDelegate { - func webView(_ webView: WebViewBridge, didStartVisitWithIdentifier identifier: String, hasCachedSnapshot: Bool) { - log("didStartVisitWithIdentifier", ["identifier": identifier, "hasCachedSnapshot": hasCachedSnapshot]) + func webView(_ webView: WebViewBridge, didStartVisitWithIdentifier identifier: String, hasCachedSnapshot: Bool, isPageRefresh: Bool) { + log("didStartVisitWithIdentifier", ["identifier": identifier, "hasCachedSnapshot": hasCachedSnapshot, "isPageRefresh": isPageRefresh]) self.identifier = identifier self.hasCachedSnapshot = hasCachedSnapshot + self.isPageRefresh = isPageRefresh delegate?.visitDidStart(self) } diff --git a/Source/Visit/Visit.swift b/Source/Visit/Visit.swift index 3b4564b..15ed413 100644 --- a/Source/Visit/Visit.swift +++ b/Source/Visit/Visit.swift @@ -18,6 +18,7 @@ class Visit: NSObject { let location: URL var hasCachedSnapshot: Bool = false + var isPageRefresh: Bool = false private(set) var state: VisitState init(visitable: Visitable, options: VisitOptions, bridge: WebViewBridge) { diff --git a/Source/WebView/ScriptMessage.swift b/Source/WebView/ScriptMessage.swift index f4c4dbc..c0abd71 100644 --- a/Source/WebView/ScriptMessage.swift +++ b/Source/WebView/ScriptMessage.swift @@ -52,6 +52,8 @@ extension ScriptMessage { case pageLoadFailed case errorRaised case visitProposed + case visitProposalScrollingToAnchor + case visitProposalRefreshingPage case visitStarted case visitRequestStarted case visitRequestCompleted diff --git a/Source/WebView/WebViewBridge.swift b/Source/WebView/WebViewBridge.swift index 9d13c35..a7bdc73 100644 --- a/Source/WebView/WebViewBridge.swift +++ b/Source/WebView/WebViewBridge.swift @@ -14,7 +14,7 @@ protocol WebViewPageLoadDelegate: AnyObject { } protocol WebViewVisitDelegate: AnyObject { - func webView(_ webView: WebViewBridge, didStartVisitWithIdentifier identifier: String, hasCachedSnapshot: Bool) + func webView(_ webView: WebViewBridge, didStartVisitWithIdentifier identifier: String, hasCachedSnapshot: Bool, isPageRefresh: Bool) func webView(_ webView: WebViewBridge, didStartRequestForVisitWithIdentifier identifier: String, date: Date) func webView(_ webView: WebViewBridge, didCompleteRequestForVisitWithIdentifier identifier: String) func webView(_ webView: WebViewBridge, didFailRequestForVisitWithIdentifier identifier: String, statusCode: Int) @@ -125,8 +125,12 @@ extension WebViewBridge: ScriptMessageHandlerDelegate { delegate?.webViewDidInvalidatePage(self) case .visitProposed: delegate?.webView(self, didProposeVisitToLocation: message.location!, options: message.options!) + case .visitProposalScrollingToAnchor: + break + case .visitProposalRefreshingPage: + break case .visitStarted: - visitDelegate?.webView(self, didStartVisitWithIdentifier: message.identifier!, hasCachedSnapshot: message.data["hasCachedSnapshot"] as! Bool) + visitDelegate?.webView(self, didStartVisitWithIdentifier: message.identifier!, hasCachedSnapshot: message.data["hasCachedSnapshot"] as! Bool, isPageRefresh: message.data["isPageRefresh"] as! Bool) case .visitRequestStarted: visitDelegate?.webView(self, didStartRequestForVisitWithIdentifier: message.identifier!, date: message.date) case .visitRequestCompleted: diff --git a/Source/WebView/turbo.js b/Source/WebView/turbo.js index 54508e5..329c90c 100644 --- a/Source/WebView/turbo.js +++ b/Source/WebView/turbo.js @@ -99,14 +99,18 @@ // Adapter interface visitProposedToLocation(location, options) { - if (window.Turbo && typeof Turbo.navigator.locationWithActionIsSamePage === "function") { - if (Turbo.navigator.locationWithActionIsSamePage(location, options.action)) { - Turbo.navigator.view.scrollToAnchorFromLocation(location) - return - } + if (window.Turbo && Turbo.navigator.locationWithActionIsSamePage(location, options.action)) { + // Scroll to the anchor on the page + this.postMessage("visitProposalScrollingToAnchor", { location: location.toString(), options: options }) + Turbo.navigator.view.scrollToAnchorFromLocation(location) + } else if (window.Turbo && Turbo.navigator.location?.href === location.href) { + // Refresh the page without native proposal + this.postMessage("visitProposalRefreshingPage", { location: location.toString(), options: options }) + this.visitLocationWithOptionsAndRestorationIdentifier(location, options, Turbo.navigator.restorationIdentifier) + } else { + // Propose the visit + this.postMessage("visitProposed", { location: location.toString(), options: options }) } - - this.postMessage("visitProposed", { location: location.toString(), options: options }) } // Turbolinks 5 @@ -116,7 +120,7 @@ visitStarted(visit) { this.currentVisit = visit - this.postMessage("visitStarted", { identifier: visit.identifier, hasCachedSnapshot: visit.hasCachedSnapshot() }) + this.postMessage("visitStarted", { identifier: visit.identifier, hasCachedSnapshot: visit.hasCachedSnapshot(), isPageRefresh: visit.isPageRefresh || false }) this.issueRequestForVisitWithIdentifier(visit.identifier) this.changeHistoryForVisitWithIdentifier(visit.identifier) this.loadCachedSnapshotForVisitWithIdentifier(visit.identifier)