Fix window.open() and target=_blank not opening in new tab (#693)

Always open programmatic navigation (window.open, target=_blank) in a new tab.
Fix insecure HTTP path to treat nil targetFrame as new-tab intent.

Closes #606

Co-authored-by: lark <lark1115caster@gmail.com>
This commit is contained in:
Lawrence Chen 2026-03-01 21:40:58 -08:00
parent bd3ee68e0c
commit 4d9587c3b0

View file

@ -3149,7 +3149,7 @@ private class BrowserNavigationDelegate: NSObject, WKNavigationDelegate {
navigationAction.targetFrame?.isMainFrame != false,
shouldBlockInsecureHTTPNavigation?(url) == true {
let intent: BrowserInsecureHTTPNavigationIntent
if shouldOpenInNewTab {
if shouldOpenInNewTab || navigationAction.targetFrame == nil {
intent = .newTab
} else {
intent = .currentTab
@ -3192,14 +3192,13 @@ private class BrowserNavigationDelegate: NSObject, WKNavigationDelegate {
return
}
// target=_blank or window.open() without explicit new-tab intent navigate in-place.
// target=_blank or window.open() open in a new tab.
if navigationAction.targetFrame == nil,
navigationAction.request.url != nil {
let url = navigationAction.request.url {
#if DEBUG
let targetURL = navigationAction.request.url?.absoluteString ?? "nil"
dlog("browser.nav.decidePolicy.action kind=loadInPlaceFromNilTarget url=\(targetURL)")
dlog("browser.nav.decidePolicy.action kind=openInNewTabFromNilTarget url=\(url.absoluteString)")
#endif
browserLoadRequest(navigationAction.request, in: webView)
openInNewTab?(url)
decisionHandler(.cancel)
return
}
@ -3306,20 +3305,16 @@ private class BrowserUIDelegate: NSObject, WKUIDelegate {
}
/// Returning nil tells WebKit not to open a new window.
/// Cmd+click and middle-click open in a new tab; regular target=_blank navigates in-place.
/// createWebViewWith is only called when the page requests a new window
/// (window.open(), target=_blank, etc.). Always open in a new tab.
func webView(
_ webView: WKWebView,
createWebViewWith configuration: WKWebViewConfiguration,
for navigationAction: WKNavigationAction,
windowFeatures: WKWindowFeatures
) -> WKWebView? {
let hasRecentMiddleClickIntent = CmuxWebView.hasRecentMiddleClickIntent(for: webView)
let shouldOpenInNewTab = browserNavigationShouldOpenInNewTab(
navigationType: navigationAction.navigationType,
modifierFlags: navigationAction.modifierFlags,
buttonNumber: navigationAction.buttonNumber,
hasRecentMiddleClickIntent: hasRecentMiddleClickIntent
)
// createWebViewWith is only called when the page requests a new window,
// so always treat as new-tab intent regardless of modifiers/button.
#if DEBUG
let currentEventType = NSApp.currentEvent.map { String(describing: $0.type) } ?? "nil"
let currentEventButton = NSApp.currentEvent.map { String($0.buttonNumber) } ?? "nil"
@ -3328,8 +3323,7 @@ private class BrowserUIDelegate: NSObject, WKUIDelegate {
"browser.nav.createWebView navType=\(navType) button=\(navigationAction.buttonNumber) " +
"mods=\(navigationAction.modifierFlags.rawValue) targetNil=\(navigationAction.targetFrame == nil ? 1 : 0) " +
"eventType=\(currentEventType) eventButton=\(currentEventButton) " +
"recentMiddleIntent=\(hasRecentMiddleClickIntent ? 1 : 0) " +
"openInNewTab=\(shouldOpenInNewTab ? 1 : 0)"
"openInNewTab=1"
)
#endif
if let url = navigationAction.request.url {
@ -3344,25 +3338,19 @@ private class BrowserUIDelegate: NSObject, WKUIDelegate {
return nil
}
if let requestNavigation {
let intent: BrowserInsecureHTTPNavigationIntent =
shouldOpenInNewTab ? .newTab : .currentTab
let intent: BrowserInsecureHTTPNavigationIntent = .newTab
#if DEBUG
dlog(
"browser.nav.createWebView.action kind=requestNavigation intent=\(intent == .newTab ? "newTab" : "currentTab") " +
"browser.nav.createWebView.action kind=requestNavigation intent=newTab " +
"url=\(url.absoluteString)"
)
#endif
requestNavigation(navigationAction.request, intent)
} else if shouldOpenInNewTab {
} else {
#if DEBUG
dlog("browser.nav.createWebView.action kind=openInNewTab url=\(url.absoluteString)")
#endif
openInNewTab?(url)
} else {
#if DEBUG
dlog("browser.nav.createWebView.action kind=loadInPlace url=\(url.absoluteString)")
#endif
browserLoadRequest(navigationAction.request, in: webView)
}
}
return nil