diff --git a/Source/Turbo/Session/Session.swift b/Source/Turbo/Session/Session.swift index d64ec17..a7f7efc 100644 --- a/Source/Turbo/Session/Session.swift +++ b/Source/Turbo/Session/Session.swift @@ -37,6 +37,7 @@ public class Session: NSObject { private var currentVisit: Visit? private var topmostVisit: Visit? + private var disappearingVisitForSnapshotting: Visit? /// The topmost visitable is the visitable that has most recently completed a visit public var topmostVisitable: Visitable? { @@ -227,6 +228,9 @@ extension Session: VisitDelegate { extension Session: VisitableDelegate { public func visitableViewWillAppear(_ visitable: Visitable) { + let lastDisappearingVisit = disappearingVisitForSnapshotting + disappearingVisitForSnapshotting = nil + guard let topmostVisit = topmostVisit, let currentVisit = currentVisit else { return } if isSnapshotCacheStale { @@ -247,7 +251,7 @@ extension Session: VisitableDelegate { } else if visitable === currentVisit.visitable && currentVisit.state == .started { // Navigating forward - complete navigation early completeNavigationForCurrentVisit() - } else if visitable !== topmostVisit.visitable { + } else if visitable !== topmostVisit.visitable || visitable === lastDisappearingVisit?.visitable { // Navigating backward visit(visitable, action: .restore) } @@ -266,6 +270,15 @@ extension Session: VisitableDelegate { } } + public func visitableViewWillDisappear(_ visitable: Visitable) { + disappearingVisitForSnapshotting = topmostVisit + } + + public func visitableViewDidDisappear(_ visitable: Visitable) { + disappearingVisitForSnapshotting?.cacheSnapshot() + deactivateVisitable(visitable) + } + public func visitableDidRequestReload(_ visitable: Visitable) { guard visitable === topmostVisitable else { return } reload() diff --git a/Source/Turbo/Visit/Visit.swift b/Source/Turbo/Visit/Visit.swift index fa5d77b..8134473 100644 --- a/Source/Turbo/Visit/Visit.swift +++ b/Source/Turbo/Visit/Visit.swift @@ -68,6 +68,10 @@ class Visit: NSObject { delegate?.visitDidFinish(self) } + func cacheSnapshot() { + bridge.cacheSnapshot() + } + func startVisit() {} func cancelVisit() {} func completeVisit() {} diff --git a/Source/Turbo/Visitable/Visitable.swift b/Source/Turbo/Visitable/Visitable.swift index 0c6f003..ec27bde 100644 --- a/Source/Turbo/Visitable/Visitable.swift +++ b/Source/Turbo/Visitable/Visitable.swift @@ -4,6 +4,8 @@ import WebKit public protocol VisitableDelegate: AnyObject { func visitableViewWillAppear(_ visitable: Visitable) func visitableViewDidAppear(_ visitable: Visitable) + func visitableViewWillDisappear(_ visitable: Visitable) + func visitableViewDidDisappear(_ visitable: Visitable) func visitableDidRequestReload(_ visitable: Visitable) func visitableDidRequestRefresh(_ visitable: Visitable) } diff --git a/Source/Turbo/Visitable/VisitableViewController.swift b/Source/Turbo/Visitable/VisitableViewController.swift index a87ab2c..6efb7b1 100644 --- a/Source/Turbo/Visitable/VisitableViewController.swift +++ b/Source/Turbo/Visitable/VisitableViewController.swift @@ -28,6 +28,16 @@ open class VisitableViewController: UIViewController, Visitable { visitableDelegate?.visitableViewDidAppear(self) } + override open func viewWillDisappear(_ animated: Bool) { + super.viewWillDisappear(animated) + visitableDelegate?.visitableViewWillDisappear(self) + } + + override open func viewDidDisappear(_ animated: Bool) { + super.viewDidDisappear(animated) + visitableDelegate?.visitableViewDidDisappear(self) + } + // MARK: Visitable open func visitableDidRender() { diff --git a/Source/Turbo/WebView/WebViewBridge.swift b/Source/Turbo/WebView/WebViewBridge.swift index 32ecffa..31cbd05 100644 --- a/Source/Turbo/WebView/WebViewBridge.swift +++ b/Source/Turbo/WebView/WebViewBridge.swift @@ -68,6 +68,10 @@ final class WebViewBridge { callJavaScript(function: "window.turboNative.clearSnapshotCache") } + func cacheSnapshot() { + callJavaScript(function: "window.turboNative.cacheSnapshot") + } + func cancelVisit(withIdentifier identifier: String) { callJavaScript(function: "window.turboNative.cancelVisitWithIdentifier", arguments: [identifier]) } diff --git a/Source/Turbo/WebView/turbo.js b/Source/Turbo/WebView/turbo.js index 329c90c..ec66870 100644 --- a/Source/Turbo/WebView/turbo.js +++ b/Source/Turbo/WebView/turbo.js @@ -57,13 +57,19 @@ } } } - + clearSnapshotCache() { if (window.Turbo) { Turbo.session.clearCache() } } + cacheSnapshot() { + if (window.Turbo) { + Turbo.session.view.cacheSnapshot() + } + } + // Current visit issueRequestForVisitWithIdentifier(identifier) { @@ -150,7 +156,7 @@ visitCompleted(visit) { this.postMessage("visitCompleted", { identifier: visit.identifier, restorationIdentifier: visit.restorationIdentifier }) } - + formSubmissionStarted(formSubmission) { this.postMessage("formSubmissionStarted", { location: formSubmission.location.toString() }) }