mirror of
https://github.com/kiwix/kiwix-apple.git
synced 2025-09-26 21:39:37 -04:00
Fix opening new tabs on macos(#518)
This commit is contained in:
parent
fba629ba98
commit
fa16cfa28f
@ -130,7 +130,7 @@ private struct Content: View {
|
|||||||
.focusedSceneValue(\.browserViewModel, browser)
|
.focusedSceneValue(\.browserViewModel, browser)
|
||||||
.focusedSceneValue(\.canGoBack, browser.canGoBack)
|
.focusedSceneValue(\.canGoBack, browser.canGoBack)
|
||||||
.focusedSceneValue(\.canGoForward, browser.canGoForward)
|
.focusedSceneValue(\.canGoForward, browser.canGoForward)
|
||||||
.modifier(ExternalLinkHandler())
|
.modifier(ExternalLinkHandler(externalURL: browser.externalURL))
|
||||||
.onAppear {
|
.onAppear {
|
||||||
browser.updateLastOpened()
|
browser.updateLastOpened()
|
||||||
}
|
}
|
||||||
|
@ -16,6 +16,10 @@ extension URL {
|
|||||||
var isKiwixURL: Bool {
|
var isKiwixURL: Bool {
|
||||||
return scheme?.caseInsensitiveCompare("kiwix") == .orderedSame
|
return scheme?.caseInsensitiveCompare("kiwix") == .orderedSame
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var isExternal: Bool {
|
||||||
|
["http", "https"].contains(scheme)
|
||||||
|
}
|
||||||
|
|
||||||
static let documentDirectory = try! FileManager.default.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: false)
|
static let documentDirectory = try! FileManager.default.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: false)
|
||||||
}
|
}
|
||||||
|
@ -13,9 +13,9 @@ import WebKit
|
|||||||
|
|
||||||
import OrderedCollections
|
import OrderedCollections
|
||||||
|
|
||||||
class BrowserViewModel: NSObject, ObservableObject,
|
final class BrowserViewModel: NSObject, ObservableObject,
|
||||||
WKNavigationDelegate, WKScriptMessageHandler, WKUIDelegate,
|
WKNavigationDelegate, WKScriptMessageHandler, WKUIDelegate,
|
||||||
NSFetchedResultsControllerDelegate
|
NSFetchedResultsControllerDelegate
|
||||||
{
|
{
|
||||||
static private var cache = OrderedDictionary<NSManagedObjectID, BrowserViewModel>()
|
static private var cache = OrderedDictionary<NSManagedObjectID, BrowserViewModel>()
|
||||||
|
|
||||||
@ -45,14 +45,17 @@ class BrowserViewModel: NSObject, ObservableObject,
|
|||||||
@Published private(set) var outlineItems = [OutlineItem]()
|
@Published private(set) var outlineItems = [OutlineItem]()
|
||||||
@Published private(set) var outlineItemTree = [OutlineItem]()
|
@Published private(set) var outlineItemTree = [OutlineItem]()
|
||||||
@Published private(set) var url: URL?
|
@Published private(set) var url: URL?
|
||||||
|
@Published var externalURL: URL?
|
||||||
|
|
||||||
let tabID: NSManagedObjectID?
|
let tabID: NSManagedObjectID?
|
||||||
let webView: WKWebView
|
let webView: WKWebView
|
||||||
private var canGoBackObserver: NSKeyValueObservation?
|
private var canGoBackObserver: NSKeyValueObservation?
|
||||||
private var canGoForwardObserver: NSKeyValueObservation?
|
private var canGoForwardObserver: NSKeyValueObservation?
|
||||||
private var titleURLObserver: AnyCancellable?
|
private var titleURLObserver: AnyCancellable?
|
||||||
private var bookmarkFetchedResultsController: NSFetchedResultsController<Bookmark>?
|
private var bookmarkFetchedResultsController: NSFetchedResultsController<Bookmark>?
|
||||||
|
/// A temporary placeholder for the url that should be opened in a new tab, set on macOS only
|
||||||
|
private static var urlForNewTab: URL?
|
||||||
|
|
||||||
// MARK: - Lifecycle
|
// MARK: - Lifecycle
|
||||||
|
|
||||||
init(tabID: NSManagedObjectID? = nil) {
|
init(tabID: NSManagedObjectID? = nil) {
|
||||||
@ -66,7 +69,11 @@ class BrowserViewModel: NSObject, ObservableObject,
|
|||||||
webView.interactionState = tab.interactionState
|
webView.interactionState = tab.interactionState
|
||||||
url = webView.url
|
url = webView.url
|
||||||
}
|
}
|
||||||
|
if let urlForNewTab = Self.urlForNewTab {
|
||||||
|
url = urlForNewTab
|
||||||
|
load(url: urlForNewTab)
|
||||||
|
}
|
||||||
|
|
||||||
// configure web view
|
// configure web view
|
||||||
webView.allowsBackForwardNavigationGestures = true
|
webView.allowsBackForwardNavigationGestures = true
|
||||||
webView.configuration.defaultWebpagePreferences.preferredContentMode = .mobile // for font adjustment to work
|
webView.configuration.defaultWebpagePreferences.preferredContentMode = .mobile // for font adjustment to work
|
||||||
@ -178,8 +185,8 @@ class BrowserViewModel: NSObject, ObservableObject,
|
|||||||
decisionHandler(.cancel)
|
decisionHandler(.cancel)
|
||||||
} else if url.isKiwixURL {
|
} else if url.isKiwixURL {
|
||||||
decisionHandler(.allow)
|
decisionHandler(.allow)
|
||||||
} else if url.scheme == "http" || url.scheme == "https" {
|
} else if url.isExternal {
|
||||||
NotificationCenter.default.post(name: .externalLink, object: nil, userInfo: ["url": url])
|
externalURL = url
|
||||||
decisionHandler(.cancel)
|
decisionHandler(.cancel)
|
||||||
} else if url.scheme == "geo" {
|
} else if url.scheme == "geo" {
|
||||||
if FeatureFlags.map {
|
if FeatureFlags.map {
|
||||||
@ -234,7 +241,34 @@ class BrowserViewModel: NSObject, ObservableObject,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// MARK: - WKUIDelegate
|
// MARK: - WKUIDelegate
|
||||||
|
#if os(macOS)
|
||||||
|
func webView(_ webView: WKWebView, createWebViewWith configuration: WKWebViewConfiguration,
|
||||||
|
for navigationAction: WKNavigationAction, windowFeatures: WKWindowFeatures) -> WKWebView? {
|
||||||
|
|
||||||
|
guard navigationAction.targetFrame == nil else { return nil }
|
||||||
|
guard let newUrl = navigationAction.request.url else { return nil }
|
||||||
|
|
||||||
|
// open external link in default browser
|
||||||
|
guard newUrl.isExternal == false else {
|
||||||
|
externalURL = newUrl
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// create new tab
|
||||||
|
guard let currentWindow = NSApp.keyWindow,
|
||||||
|
let windowController = currentWindow.windowController else { return nil }
|
||||||
|
// store the new url in a static way
|
||||||
|
Self.urlForNewTab = newUrl
|
||||||
|
// this creates a new BrowserViewModel
|
||||||
|
windowController.newWindowForTab(self)
|
||||||
|
// now reset the static url to nil, as the new BrowserViewModel already has it
|
||||||
|
Self.urlForNewTab = nil
|
||||||
|
guard let newWindow = NSApp.keyWindow, currentWindow != newWindow else { return nil }
|
||||||
|
currentWindow.addTabbedWindow(newWindow, ordered: .above)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#if os(iOS)
|
#if os(iOS)
|
||||||
func webView(_ webView: WKWebView,
|
func webView(_ webView: WKWebView,
|
||||||
contextMenuConfigurationForElement elementInfo: WKContextMenuElementInfo,
|
contextMenuConfigurationForElement elementInfo: WKContextMenuElementInfo,
|
||||||
|
@ -38,7 +38,7 @@ struct BrowserTab: View {
|
|||||||
.focusedSceneValue(\.browserViewModel, browser)
|
.focusedSceneValue(\.browserViewModel, browser)
|
||||||
.focusedSceneValue(\.canGoBack, browser.canGoBack)
|
.focusedSceneValue(\.canGoBack, browser.canGoBack)
|
||||||
.focusedSceneValue(\.canGoForward, browser.canGoForward)
|
.focusedSceneValue(\.canGoForward, browser.canGoForward)
|
||||||
.modifier(ExternalLinkHandler())
|
.modifier(ExternalLinkHandler(externalURL: $browser.externalURL))
|
||||||
.searchable(text: $search.searchText, placement: .toolbar)
|
.searchable(text: $search.searchText, placement: .toolbar)
|
||||||
.modify { view in
|
.modify { view in
|
||||||
#if os(macOS)
|
#if os(macOS)
|
||||||
|
@ -14,8 +14,7 @@ struct ExternalLinkHandler: ViewModifier {
|
|||||||
@State private var isAlertPresented = false
|
@State private var isAlertPresented = false
|
||||||
@State private var activeAlert: ActiveAlert?
|
@State private var activeAlert: ActiveAlert?
|
||||||
@State private var activeSheet: ActiveSheet?
|
@State private var activeSheet: ActiveSheet?
|
||||||
|
@Binding var externalURL: URL?
|
||||||
private let externalLink = NotificationCenter.default.publisher(for: .externalLink)
|
|
||||||
|
|
||||||
enum ActiveAlert {
|
enum ActiveAlert {
|
||||||
case ask(url: URL)
|
case ask(url: URL)
|
||||||
@ -28,8 +27,8 @@ struct ExternalLinkHandler: ViewModifier {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func body(content: Content) -> some View {
|
func body(content: Content) -> some View {
|
||||||
content.onReceive(externalLink) { notification in
|
content.onChange(of: externalURL) { url in
|
||||||
guard let url = notification.userInfo?["url"] as? URL else { return }
|
guard let url else { return }
|
||||||
switch Defaults[.externalLinkLoadingPolicy] {
|
switch Defaults[.externalLinkLoadingPolicy] {
|
||||||
case .alwaysAsk:
|
case .alwaysAsk:
|
||||||
isAlertPresented = true
|
isAlertPresented = true
|
||||||
|
Loading…
x
Reference in New Issue
Block a user