diff --git a/Sources/Panels/BrowserPanel.swift b/Sources/Panels/BrowserPanel.swift index da61b37e..827b6b28 100644 --- a/Sources/Panels/BrowserPanel.swift +++ b/Sources/Panels/BrowserPanel.swift @@ -2525,6 +2525,7 @@ final class BrowserPanel: Panel, ObservableObject { navigationDelegate.didFinish = { [weak self] webView in Task { @MainActor [weak self] in guard let self, self.isCurrentWebView(webView, instanceID: boundWebViewInstanceID) else { return } + self.realignRestoredSessionHistoryToLiveCurrentIfPossible() boundHistoryStore.recordVisit(url: webView.url, title: webView.title) self.refreshFavicon(from: webView) self.applyBrowserThemeModeIfNeeded() @@ -2867,20 +2868,109 @@ final class BrowserPanel: Panel, ObservableObject { backHistoryURLStrings: [String], forwardHistoryURLStrings: [String] ) { + realignRestoredSessionHistoryToLiveCurrentIfPossible() + + let nativeBack = webView.backForwardList.backList.compactMap { + Self.serializableSessionHistoryURLString($0.url) + } + let nativeForward = webView.backForwardList.forwardList.compactMap { + Self.serializableSessionHistoryURLString($0.url) + } + if usesRestoredSessionHistory { let back = restoredBackHistoryStack.compactMap { Self.serializableSessionHistoryURLString($0) } // `restoredForwardHistoryStack` stores nearest-forward entries at the end. - let forward = restoredForwardHistoryStack.reversed().compactMap { Self.serializableSessionHistoryURLString($0) } - return (back, forward) + let restoredForward = restoredForwardHistoryStack.reversed().compactMap { + Self.serializableSessionHistoryURLString($0) + } + + if isLiveSessionHistoryAlignedWithRestoredCurrent { + return ( + back, + restoredForward.isEmpty ? nativeForward : restoredForward + ) + } + + return (back + nativeBack, nativeForward) } - let back = webView.backForwardList.backList.compactMap { - Self.serializableSessionHistoryURLString($0.url) + return (nativeBack, nativeForward) + } + + private func resolvedLiveSessionHistoryURL() -> URL? { + if let webViewURL = Self.remoteProxyDisplayURL(for: webView.url), + Self.serializableSessionHistoryURLString(webViewURL) != nil { + return webViewURL } - let forward = webView.backForwardList.forwardList.compactMap { - Self.serializableSessionHistoryURLString($0.url) + if let currentURL, + Self.serializableSessionHistoryURLString(currentURL) != nil { + return currentURL } - return (back, forward) + return nil + } + + private var isLiveSessionHistoryAlignedWithRestoredCurrent: Bool { + let liveCurrent = Self.serializableSessionHistoryURLString(resolvedLiveSessionHistoryURL()) + let restoredCurrent = Self.serializableSessionHistoryURLString(restoredHistoryCurrentURL) + guard let liveCurrent, let restoredCurrent else { return true } + return liveCurrent == restoredCurrent + } + + private func realignRestoredSessionHistoryToLiveCurrentIfPossible() { + guard usesRestoredSessionHistory else { return } + guard let liveCurrent = resolvedLiveSessionHistoryURL(), + let liveCurrentString = Self.serializableSessionHistoryURLString(liveCurrent) else { + return + } + guard Self.serializableSessionHistoryURLString(restoredHistoryCurrentURL) != liveCurrentString else { + return + } + + let restoredBack = restoredBackHistoryStack.compactMap { Self.serializableSessionHistoryURLString($0) } + let restoredForward = restoredForwardHistoryStack.reversed().compactMap { + Self.serializableSessionHistoryURLString($0) + } + let restoredCurrent = Self.serializableSessionHistoryURLString(restoredHistoryCurrentURL) + + if let backIndex = restoredBack.lastIndex(of: liveCurrentString) { + let newBack = Array(restoredBack[..