Gemini/BrowserCore/NavigationManager.swift

81 lines
2.1 KiB
Swift

//
// NavigationManager.swift
// Gemini
//
// Created by Shadowfacts on 7/14/20.
//
import Foundation
public protocol NavigationManagerDelegate: class {
func loadNonGeminiURL(_ url: URL)
}
public class NavigationManager: NSObject, ObservableObject {
public weak var delegate: NavigationManagerDelegate?
@Published public var currentURL: URL
@Published public var backStack = [URL]()
@Published public var forwardStack = [URL]()
public var displayURL: String {
var components = URLComponents(url: currentURL, resolvingAgainstBaseURL: false)!
if components.port == 1965 {
components.port = nil
}
return components.string!
}
public init(url: URL) {
self.currentURL = url
}
public func changeURL(_ url: URL) {
var components = URLComponents(url: url, resolvingAgainstBaseURL: false)!
if let scheme = url.scheme {
if scheme != "gemini" {
delegate?.loadNonGeminiURL(url)
return
}
} else {
components.scheme = "gemini"
}
// Foundation parses bare hosts (e.g. `example.com`) as having no host and a path of `example.com`
if components.host == nil {
components.host = components.path
components.path = "/"
}
// Some Gemini servers break on empty paths
if components.path.isEmpty {
components.path = "/"
}
let url = components.url!
backStack.append(currentURL)
currentURL = url
forwardStack = []
}
public func reload() {
let url = currentURL
currentURL = url
}
@objc public func back() {
guard !backStack.isEmpty else { return }
forwardStack.insert(currentURL, at: 0)
currentURL = backStack.removeLast()
}
@objc public func forward() {
guard !forwardStack.isEmpty else { return }
backStack.append(currentURL)
currentURL = forwardStack.removeFirst()
}
}